From: Vsevolod Stakhov Date: Mon, 9 Feb 2026 10:44:36 +0000 (+0000) Subject: [Feature] Implement HTTPS server support for workers X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9a3d1c0f1795ecb9ba55f103b2667d6ffdd73110;p=thirdparty%2Frspamd.git [Feature] Implement HTTPS server support for workers Wire up server-side SSL/TLS for HTTP workers, building on the recently added rspamd_ssl_accept_fd() infrastructure. This enables HTTPS for controller, normal, and proxy workers with per-bind-address granularity. Configuration: `bind_socket = "*:11335 ssl"` plus `ssl_cert` and `ssl_key` worker options. - Add rspamd_init_ssl_ctx_server() for server SSL_CTX with cert+key - Parse trailing " ssl" suffix in bind_socket lines - Propagate is_ssl flag through bind conf to listen sockets - Add rspamd_http_connection_accept_ssl() for async SSL handshake - Fix write_message_common to handle server-side SSL responses - Add SSL support to HTTP router (set_ssl, handle_socket_ssl) - Wire up SSL in controller, normal worker, and proxy worker - Add rspamd_worker_is_ssl_socket() utility for fd-to-SSL lookup --- diff --git a/src/controller.c b/src/controller.c index 286dbebe54..73a83d1f36 100644 --- a/src/controller.c +++ b/src/controller.c @@ -25,6 +25,7 @@ #include "libstat/stat_api.h" #include "rspamd.h" #include "libserver/worker_util.h" +#include "libserver/ssl_util.h" #include "worker_private.h" #include "lua/lua_common.h" #include "cryptobox.h" @@ -3657,7 +3658,8 @@ rspamd_controller_accept_socket(EV_P_ ev_io *w, int revents) session->wrk = worker; worker->nconns++; - rspamd_http_router_handle_socket(ctx->http, nfd, session); + rspamd_http_router_handle_socket_ssl(ctx->http, nfd, session, + rspamd_worker_is_ssl_socket(worker, w->fd)); } static void @@ -3726,7 +3728,7 @@ init_controller_worker(struct rspamd_config *cfg) ctx, G_STRUCT_OFFSET(struct rspamd_controller_worker_ctx, use_ssl), 0, - "Unimplemented"); + "Enable SSL for this worker"); rspamd_rcl_register_worker_option(cfg, type, @@ -3735,7 +3737,7 @@ init_controller_worker(struct rspamd_config *cfg) ctx, G_STRUCT_OFFSET(struct rspamd_controller_worker_ctx, ssl_cert), 0, - "Unimplemented"); + "Path to SSL certificate chain file"); rspamd_rcl_register_worker_option(cfg, type, @@ -3744,7 +3746,7 @@ init_controller_worker(struct rspamd_config *cfg) ctx, G_STRUCT_OFFSET(struct rspamd_controller_worker_ctx, ssl_key), 0, - "Unimplemented"); + "Path to SSL private key file"); rspamd_rcl_register_worker_option(cfg, type, "timeout", @@ -4117,6 +4119,19 @@ start_controller_worker(struct rspamd_worker *worker) rspamd_controller_finish_handler, ctx->timeout, ctx->static_files_dir, ctx->http_ctx); + if (ctx->use_ssl && ctx->ssl_cert && ctx->ssl_key) { + gpointer server_ssl_ctx = rspamd_init_ssl_ctx_server(ctx->ssl_cert, ctx->ssl_key); + + if (server_ssl_ctx) { + rspamd_ssl_ctx_config(ctx->cfg, server_ssl_ctx); + rspamd_http_router_set_ssl(ctx->http, server_ssl_ctx); + msg_info_ctx("enabled SSL for controller worker"); + } + else { + msg_err_ctx("failed to create SSL context for controller worker"); + } + } + /* Add callbacks for different methods */ rspamd_http_router_add_path(ctx->http, PATH_AUTH, diff --git a/src/libserver/cfg_file.h b/src/libserver/cfg_file.h index ed0c1f1670..5b9022e2db 100644 --- a/src/libserver/cfg_file.h +++ b/src/libserver/cfg_file.h @@ -196,6 +196,7 @@ struct rspamd_worker_bind_conf { char *name; char *bind_line; gboolean is_systemd; + gboolean is_ssl; struct rspamd_worker_bind_conf *next; }; diff --git a/src/libserver/cfg_utils.cxx b/src/libserver/cfg_utils.cxx index a70473adc4..edee9cb898 100644 --- a/src/libserver/cfg_utils.cxx +++ b/src/libserver/cfg_utils.cxx @@ -189,6 +189,18 @@ rspamd_parse_bind_line(struct rspamd_config *cfg, auto bind_line = std::string_view{cnf->bind_line}; + /* Check for trailing " ssl" suffix (case-insensitive) */ + if (bind_line.size() > 4 && + bind_line[bind_line.size() - 4] == ' ' && + g_ascii_tolower(bind_line[bind_line.size() - 3]) == 's' && + g_ascii_tolower(bind_line[bind_line.size() - 2]) == 's' && + g_ascii_tolower(bind_line[bind_line.size() - 1]) == 'l') { + cnf->is_ssl = TRUE; + /* Strip the suffix for address parsing */ + cnf->bind_line[bind_line.size() - 4] = '\0'; + bind_line = std::string_view{cnf->bind_line}; + } + if (bind_line.starts_with("systemd:")) { /* The actual socket will be passed by systemd environment */ fdname = str + sizeof("systemd:") - 1; diff --git a/src/libserver/http/http_connection.c b/src/libserver/http/http_connection.c index 1835071658..117d2e4334 100644 --- a/src/libserver/http/http_connection.c +++ b/src/libserver/http/http_connection.c @@ -2573,6 +2573,14 @@ if (conn->opts & RSPAMD_HTTP_CLIENT_SSL) { } } } +else if (priv->ssl) { + /* Server-side SSL: connection already established, restore handlers */ + rspamd_ssl_connection_restore_handlers(priv->ssl, + rspamd_http_event_handler, + rspamd_http_ssl_err_handler, + conn, + EV_WRITE); +} else { /* Watch for READ too on client to detect early server responses */ short ev_flags = (conn->type == RSPAMD_HTTP_CLIENT) ? (EV_WRITE | EV_READ) : EV_WRITE; @@ -2897,3 +2905,90 @@ double rspamd_http_connection_keepalive_idle_timeout(struct rspamd_http_connecti struct rspamd_http_connection_private *priv = conn->priv; return (priv->ka_idle_override > 0 ? priv->ka_idle_override : default_idle); } + +static void +rspamd_http_ssl_accept_handler(int fd, short what, gpointer ud) +{ + struct rspamd_http_connection *conn = (struct rspamd_http_connection *) ud; + struct rspamd_http_connection_private *priv = conn->priv; + + /* SSL handshake complete, start reading HTTP message */ + rspamd_http_connection_read_message_common(conn, conn->ud, priv->timeout, 0); +} + +static void +rspamd_http_ssl_accept_shared_handler(int fd, short what, gpointer ud) +{ + struct rspamd_http_connection *conn = (struct rspamd_http_connection *) ud; + struct rspamd_http_connection_private *priv = conn->priv; + + /* SSL handshake complete, start reading HTTP message with shared body */ + rspamd_http_connection_read_message_common(conn, conn->ud, priv->timeout, + RSPAMD_HTTP_FLAG_SHMEM); +} + +static gboolean +rspamd_http_connection_accept_ssl_common(struct rspamd_http_connection *conn, + gpointer ssl_ctx, + gpointer ud, + ev_tstamp timeout, + rspamd_ssl_handler_t accept_handler) +{ + struct rspamd_http_connection_private *priv = conn->priv; + GError *err; + + g_assert(conn != NULL); + g_assert(ssl_ctx != NULL); + + conn->ud = ud; + priv->timeout = timeout; + + priv->ssl = rspamd_ssl_connection_new(ssl_ctx, priv->ctx->event_loop, + FALSE, conn->log_tag); + + if (priv->ssl == NULL) { + err = g_error_new(HTTP_ERROR, 400, "cannot create SSL connection"); + rspamd_http_connection_ref(conn); + conn->error_handler(conn, err); + rspamd_http_connection_unref(conn); + g_error_free(err); + return FALSE; + } + + if (!rspamd_ssl_accept_fd(priv->ssl, conn->fd, &priv->ev, + timeout, accept_handler, + rspamd_http_ssl_err_handler, conn)) { + + err = g_error_new(HTTP_ERROR, 400, + "ssl accept error: ssl error=%s, errno=%s", + ERR_error_string(ERR_get_error(), NULL), + strerror(errno)); + rspamd_http_connection_ref(conn); + conn->error_handler(conn, err); + rspamd_http_connection_unref(conn); + g_error_free(err); + return FALSE; + } + + return TRUE; +} + +gboolean +rspamd_http_connection_accept_ssl(struct rspamd_http_connection *conn, + gpointer ssl_ctx, + gpointer ud, + ev_tstamp timeout) +{ + return rspamd_http_connection_accept_ssl_common(conn, ssl_ctx, ud, timeout, + rspamd_http_ssl_accept_handler); +} + +gboolean +rspamd_http_connection_accept_ssl_shared(struct rspamd_http_connection *conn, + gpointer ssl_ctx, + gpointer ud, + ev_tstamp timeout) +{ + return rspamd_http_connection_accept_ssl_common(conn, ssl_ctx, ud, timeout, + rspamd_http_ssl_accept_shared_handler); +} diff --git a/src/libserver/http/http_connection.h b/src/libserver/http/http_connection.h index 879417b9f8..32a902d5bf 100644 --- a/src/libserver/http/http_connection.h +++ b/src/libserver/http/http_connection.h @@ -345,6 +345,29 @@ void rspamd_http_connection_set_max_size(struct rspamd_http_connection *conn, void rspamd_http_connection_disable_encryption(struct rspamd_http_connection *conn); +/** + * Accept SSL on an existing server connection. Performs the SSL handshake + * asynchronously and then starts HTTP message reading. + * @param conn server connection (already created via rspamd_http_connection_new_server) + * @param ssl_ctx server SSL context (from rspamd_init_ssl_ctx_server) + * @param ud opaque user data + * @param timeout handshake/IO timeout + * @return TRUE if handshake was initiated + */ +gboolean rspamd_http_connection_accept_ssl(struct rspamd_http_connection *conn, + gpointer ssl_ctx, + gpointer ud, + ev_tstamp timeout); + +/** + * Accept SSL on an existing server connection with shared memory body. + * Same as rspamd_http_connection_accept_ssl but starts reading in shared mode. + */ +gboolean rspamd_http_connection_accept_ssl_shared(struct rspamd_http_connection *conn, + gpointer ssl_ctx, + gpointer ud, + ev_tstamp timeout); + #ifdef __cplusplus } #endif diff --git a/src/libserver/http/http_router.c b/src/libserver/http/http_router.c index fd47246050..b5255e0e46 100644 --- a/src/libserver/http/http_router.c +++ b/src/libserver/http/http_router.c @@ -18,6 +18,7 @@ #include "http_connection.h" #include "http_private.h" #include "libserver/http_content_negotiation.h" +#include "libserver/ssl_util.h" #include "libutil/regexp.h" #include "libutil/printf.h" #include "libserver/logger.h" @@ -515,8 +516,15 @@ void rspamd_http_router_add_regexp(struct rspamd_http_connection_router *router, } } -void rspamd_http_router_handle_socket(struct rspamd_http_connection_router *router, - int fd, gpointer ud) +void rspamd_http_router_set_ssl(struct rspamd_http_connection_router *router, + gpointer ssl_ctx) +{ + g_assert(router != NULL); + router->server_ssl_ctx = ssl_ctx; +} + +void rspamd_http_router_handle_socket_ssl(struct rspamd_http_connection_router *router, + int fd, gpointer ud, gboolean ssl) { struct rspamd_http_connection_entry *conn; @@ -536,10 +544,23 @@ void rspamd_http_router_handle_socket(struct rspamd_http_connection_router *rout rspamd_http_connection_set_key(conn->conn, router->key); } - rspamd_http_connection_read_message(conn->conn, conn, router->timeout); + if (ssl && router->server_ssl_ctx) { + rspamd_http_connection_accept_ssl(conn->conn, router->server_ssl_ctx, + conn, router->timeout); + } + else { + rspamd_http_connection_read_message(conn->conn, conn, router->timeout); + } + DL_PREPEND(router->conns, conn); } +void rspamd_http_router_handle_socket(struct rspamd_http_connection_router *router, + int fd, gpointer ud) +{ + rspamd_http_router_handle_socket_ssl(router, fd, ud, FALSE); +} + void rspamd_http_router_free(struct rspamd_http_connection_router *router) { struct rspamd_http_connection_entry *conn, *tmp; @@ -556,6 +577,10 @@ void rspamd_http_router_free(struct rspamd_http_connection_router *router) rspamd_keypair_unref(router->key); } + if (router->server_ssl_ctx) { + rspamd_ssl_ctx_free(router->server_ssl_ctx); + } + if (router->default_fs_path != NULL) { g_free(router->default_fs_path); } diff --git a/src/libserver/http/http_router.h b/src/libserver/http/http_router.h index 6977d6e736..f3ce54effc 100644 --- a/src/libserver/http/http_router.h +++ b/src/libserver/http/http_router.h @@ -59,6 +59,7 @@ struct rspamd_http_connection_router { struct rspamd_cryptobox_keypair *key; rspamd_http_router_error_handler_t error_handler; rspamd_http_router_finish_handler_t finish_handler; + gpointer server_ssl_ctx; }; /** @@ -126,6 +127,14 @@ struct rspamd_regexp_s; void rspamd_http_router_add_regexp(struct rspamd_http_connection_router *router, struct rspamd_regexp_s *re, rspamd_http_router_handler_t handler); +/** + * Set server SSL context for the router + * @param router router object + * @param ssl_ctx server SSL context (from rspamd_init_ssl_ctx_server) + */ +void rspamd_http_router_set_ssl(struct rspamd_http_connection_router *router, + gpointer ssl_ctx); + /** * Handle new accepted socket * @param router router object @@ -137,6 +146,19 @@ void rspamd_http_router_handle_socket( int fd, gpointer ud); +/** + * Handle new accepted socket with optional SSL + * @param router router object + * @param fd server socket + * @param ud opaque userdata + * @param ssl whether to use SSL on this socket + */ +void rspamd_http_router_handle_socket_ssl( + struct rspamd_http_connection_router *router, + int fd, + gpointer ud, + gboolean ssl); + /** * Free router and all connections associated * @param router diff --git a/src/libserver/ssl_util.c b/src/libserver/ssl_util.c index f41d310579..af2b360ac4 100644 --- a/src/libserver/ssl_util.c +++ b/src/libserver/ssl_util.c @@ -1170,6 +1170,51 @@ gpointer rspamd_init_ssl_ctx_noverify(void) return ssl_ctx_noverify; } + +gpointer +rspamd_init_ssl_ctx_server(const char *cert_path, const char *key_path) +{ + struct rspamd_ssl_ctx *ctx; + + g_assert(cert_path != NULL); + g_assert(key_path != NULL); + + ctx = rspamd_init_ssl_ctx_common(); + + /* Server-side session cache */ + SSL_CTX_set_session_cache_mode(ctx->s, SSL_SESS_CACHE_SERVER); + /* Remove client session callback set by common init */ + SSL_CTX_sess_set_new_cb(ctx->s, NULL); + + /* Load certificate chain */ + if (SSL_CTX_use_certificate_chain_file(ctx->s, cert_path) != 1) { + msg_err("cannot load certificate chain from %s: %s", + cert_path, ERR_error_string(ERR_get_error(), NULL)); + rspamd_ssl_ctx_free(ctx); + return NULL; + } + + /* Load private key */ + if (SSL_CTX_use_PrivateKey_file(ctx->s, key_path, SSL_FILETYPE_PEM) != 1) { + msg_err("cannot load private key from %s: %s", + key_path, ERR_error_string(ERR_get_error(), NULL)); + rspamd_ssl_ctx_free(ctx); + return NULL; + } + + /* Verify that the key matches the certificate */ + if (SSL_CTX_check_private_key(ctx->s) != 1) { + msg_err("ssl private key does not match certificate: %s", + ERR_error_string(ERR_get_error(), NULL)); + rspamd_ssl_ctx_free(ctx); + return NULL; + } + + /* No client certificate verification */ + SSL_CTX_set_verify(ctx->s, SSL_VERIFY_NONE, NULL); + + return ctx; +} #if defined(RSPAMD_LEGACY_SSL_PROVIDER) && OPENSSL_VERSION_NUMBER >= 0x30000000L #include #endif diff --git a/src/libserver/ssl_util.h b/src/libserver/ssl_util.h index 802ba96865..0a042dbff6 100644 --- a/src/libserver/ssl_util.h +++ b/src/libserver/ssl_util.h @@ -125,6 +125,7 @@ void rspamd_ssl_connection_free(struct rspamd_ssl_connection *conn); gpointer rspamd_init_ssl_ctx(void); gpointer rspamd_init_ssl_ctx_noverify(void); +gpointer rspamd_init_ssl_ctx_server(const char *cert_path, const char *key_path); void rspamd_ssl_ctx_config(struct rspamd_config *cfg, gpointer ssl_ctx); void rspamd_ssl_ctx_free(gpointer ssl_ctx); void rspamd_openssl_maybe_init(struct rspamd_external_libs_ctx *ctx); diff --git a/src/libserver/worker_util.c b/src/libserver/worker_util.c index 7c426a6cb7..c28ce36661 100644 --- a/src/libserver/worker_util.c +++ b/src/libserver/worker_util.c @@ -2889,3 +2889,28 @@ rspamd_metrics_to_prometheus_string(const ucl_object_t *top) /* Must be finalized and freed by caller */ return output; } + +gboolean +rspamd_worker_is_ssl_socket(struct rspamd_worker *worker, int fd) +{ + GList *cur; + struct rspamd_worker_listen_socket *ls; + + if (worker == NULL || worker->cf == NULL) { + return FALSE; + } + + cur = worker->cf->listen_socks; + + while (cur) { + ls = (struct rspamd_worker_listen_socket *) cur->data; + + if (ls->fd == fd) { + return ls->is_ssl; + } + + cur = g_list_next(cur); + } + + return FALSE; +} diff --git a/src/libserver/worker_util.h b/src/libserver/worker_util.h index de80b6a37b..1089c0a9cf 100644 --- a/src/libserver/worker_util.h +++ b/src/libserver/worker_util.h @@ -383,6 +383,14 @@ rspamd_metrics_add_double(rspamd_fstring_t **output, */ rspamd_fstring_t *rspamd_metrics_to_prometheus_string(const ucl_object_t *top); +/** + * Check if the given listen fd is an SSL socket for this worker + * @param worker + * @param fd listen fd from accept event + * @return TRUE if the socket is SSL + */ +gboolean rspamd_worker_is_ssl_socket(struct rspamd_worker *worker, int fd); + #ifdef WITH_HYPERSCAN struct rspamd_control_command; diff --git a/src/rspamd.c b/src/rspamd.c index fbadc59d85..7568b43f2a 100644 --- a/src/rspamd.c +++ b/src/rspamd.c @@ -708,6 +708,16 @@ spawn_workers(struct rspamd_main *rspamd_main, struct ev_loop *ev_base) strerror(errno)); } else { + /* Propagate SSL flag to listen sockets */ + if (bcf->is_ssl) { + GList *cur; + + for (cur = ls; cur != NULL; cur = g_list_next(cur)) { + struct rspamd_worker_listen_socket *cur_ls = + (struct rspamd_worker_listen_socket *) cur->data; + cur_ls->is_ssl = true; + } + } g_hash_table_insert(listen_sockets, (gpointer) key, ls); listen_ok = TRUE; } diff --git a/src/rspamd.h b/src/rspamd.h index 4c266cb50b..02901a7eaf 100644 --- a/src/rspamd.h +++ b/src/rspamd.h @@ -241,6 +241,7 @@ struct rspamd_worker_listen_socket { int fd; enum rspamd_worker_socket_type type; bool is_systemd; + bool is_ssl; }; typedef struct worker_s { diff --git a/src/rspamd_proxy.c b/src/rspamd_proxy.c index 6652970756..0f61124334 100644 --- a/src/rspamd_proxy.c +++ b/src/rspamd_proxy.c @@ -27,6 +27,7 @@ #include "libmime/message.h" #include "rspamd.h" #include "libserver/worker_util.h" +#include "libserver/ssl_util.h" #include "worker_private.h" #include "lua/lua_common.h" #include "keypairs_cache.h" @@ -180,6 +181,14 @@ struct rspamd_proxy_ctx { /* Default log tag type for worker */ enum rspamd_proxy_log_tag_type log_tag_type; struct rspamd_main *srv; + /* Whether we use ssl for this server */ + gboolean use_ssl; + /* SSL cert */ + char *ssl_cert; + /* SSL private key */ + char *ssl_key; + /* Server SSL context */ + gpointer server_ssl_ctx; }; enum rspamd_backend_flags { @@ -1056,6 +1065,30 @@ init_rspamd_proxy(struct rspamd_config *cfg) G_STRUCT_OFFSET(struct rspamd_proxy_ctx, encrypted_only), 0, "Allow only encrypted connections"); + rspamd_rcl_register_worker_option(cfg, + type, + "ssl", + rspamd_rcl_parse_struct_boolean, + ctx, + G_STRUCT_OFFSET(struct rspamd_proxy_ctx, use_ssl), + 0, + "Enable SSL for this worker"); + rspamd_rcl_register_worker_option(cfg, + type, + "ssl_cert", + rspamd_rcl_parse_struct_string, + ctx, + G_STRUCT_OFFSET(struct rspamd_proxy_ctx, ssl_cert), + 0, + "Path to SSL certificate chain file"); + rspamd_rcl_register_worker_option(cfg, + type, + "ssl_key", + rspamd_rcl_parse_struct_string, + ctx, + G_STRUCT_OFFSET(struct rspamd_proxy_ctx, ssl_key), + 0, + "Path to SSL private key file"); rspamd_rcl_register_worker_option(cfg, type, "upstream", @@ -3286,9 +3319,17 @@ proxy_accept_socket(EV_P_ ev_io *w, int revents) rspamd_inet_address_to_string(addr), rspamd_inet_address_get_port(addr)); - rspamd_http_connection_read_message_shared(session->client_conn, - session, - session->ctx->timeout); + if (ctx->server_ssl_ctx && rspamd_worker_is_ssl_socket(worker, w->fd)) { + rspamd_http_connection_accept_ssl_shared(session->client_conn, + ctx->server_ssl_ctx, + session, + session->ctx->timeout); + } + else { + rspamd_http_connection_read_message_shared(session->client_conn, + session, + session->ctx->timeout); + } } else { msg_info_session("accepted milter connection from %s port %d", @@ -3375,6 +3416,18 @@ start_rspamd_proxy(struct rspamd_worker *worker) (rspamd_mempool_destruct_t) rspamd_http_context_free, ctx->http_ctx); + if (ctx->use_ssl && ctx->ssl_cert && ctx->ssl_key) { + ctx->server_ssl_ctx = rspamd_init_ssl_ctx_server(ctx->ssl_cert, ctx->ssl_key); + + if (ctx->server_ssl_ctx) { + rspamd_ssl_ctx_config(ctx->cfg, ctx->server_ssl_ctx); + msg_info("enabled SSL for proxy worker"); + } + else { + msg_err("failed to create SSL context for proxy worker"); + } + } + if (ctx->has_self_scan) { /* Additional initialisation needed */ rspamd_worker_init_scanner(worker, ctx->event_loop, ctx->resolver, diff --git a/src/worker.c b/src/worker.c index 2d46754d87..6dc9dd9741 100644 --- a/src/worker.c +++ b/src/worker.c @@ -30,6 +30,7 @@ #include "libstat/stat_api.h" #include "libserver/worker_util.h" #include "libserver/rspamd_control.h" +#include "libserver/ssl_util.h" #include "worker_private.h" #include "libserver/http/http_private.h" #include "libserver/cfg_file_private.h" @@ -398,9 +399,17 @@ accept_socket(EV_P_ ev_io *w, int revents) rspamd_http_connection_set_key(session->http_conn, ctx->key); } - rspamd_http_connection_read_message(session->http_conn, - session, - ctx->timeout); + if (ctx->server_ssl_ctx && rspamd_worker_is_ssl_socket(worker, w->fd)) { + rspamd_http_connection_accept_ssl(session->http_conn, + ctx->server_ssl_ctx, + session, + ctx->timeout); + } + else { + rspamd_http_connection_read_message(session->http_conn, + session, + ctx->timeout); + } } gpointer @@ -478,6 +487,33 @@ init_worker(struct rspamd_config *cfg) 0, "Encryption keypair"); + rspamd_rcl_register_worker_option(cfg, + type, + "ssl", + rspamd_rcl_parse_struct_boolean, + ctx, + G_STRUCT_OFFSET(struct rspamd_worker_ctx, use_ssl), + 0, + "Enable SSL for this worker"); + + rspamd_rcl_register_worker_option(cfg, + type, + "ssl_cert", + rspamd_rcl_parse_struct_string, + ctx, + G_STRUCT_OFFSET(struct rspamd_worker_ctx, ssl_cert), + 0, + "Path to SSL certificate chain file"); + + rspamd_rcl_register_worker_option(cfg, + type, + "ssl_key", + rspamd_rcl_parse_struct_string, + ctx, + G_STRUCT_OFFSET(struct rspamd_worker_ctx, ssl_key), + 0, + "Path to SSL private key file"); + return ctx; } @@ -510,6 +546,19 @@ start_worker(struct rspamd_worker *worker) rspamd_mempool_add_destructor(ctx->cfg->cfg_pool, (rspamd_mempool_destruct_t) rspamd_http_context_free, ctx->http_ctx); + + if (ctx->use_ssl && ctx->ssl_cert && ctx->ssl_key) { + ctx->server_ssl_ctx = rspamd_init_ssl_ctx_server(ctx->ssl_cert, ctx->ssl_key); + + if (ctx->server_ssl_ctx) { + rspamd_ssl_ctx_config(ctx->cfg, ctx->server_ssl_ctx); + msg_info_ctx("enabled SSL for normal worker"); + } + else { + msg_err_ctx("failed to create SSL context for normal worker"); + } + } + rspamd_worker_init_scanner(worker, ctx->event_loop, ctx->resolver, &ctx->lang_det); diff --git a/src/worker_private.h b/src/worker_private.h index 6fb40e9704..19f6cd7b31 100644 --- a/src/worker_private.h +++ b/src/worker_private.h @@ -45,6 +45,8 @@ struct rspamd_worker_ctx { gboolean is_mime; /* Allow encrypted requests only using network */ gboolean encrypted_only; + /* Whether we use ssl for this server */ + gboolean use_ssl; /* Limit of tasks */ uint32_t max_tasks; /* Maximum time for task processing */ @@ -55,6 +57,12 @@ struct rspamd_worker_ctx { struct rspamd_http_context *http_ctx; /* Language detector */ struct rspamd_lang_detector *lang_det; + /* SSL cert */ + char *ssl_cert; + /* SSL private key */ + char *ssl_key; + /* Server SSL context */ + gpointer server_ssl_ctx; }; /*