Add custom SSL/TLS handling in upstream logic

This commit is contained in:
Kanaga Vasantharaj (WIPRO LIMITED) 2025-06-20 17:57:33 +05:30
parent 5b8a5c08ce
commit 711e66b411
6 changed files with 178 additions and 14 deletions

View File

@ -29,6 +29,36 @@ static int ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn,
const unsigned char **out, unsigned char *outlen,
const unsigned char *in, unsigned int inlen, void *arg);
#endif
u_char *ngx_ssl_get_backend_protocol(ngx_connection_t *c);
u_char *ngx_ssl_get_backend_cipher(ngx_connection_t *c);
static ngx_int_t ngx_http_backend_ssl_add_variables(ngx_conf_t *cf);
static ngx_int_t ngx_http_variable_backend_ssl_cipher(ngx_http_request_t *r,
ngx_http_variable_value_t *v,
uintptr_t data);
static ngx_int_t ngx_http_variable_backend_ssl_protocol(ngx_http_request_t *r,
ngx_http_variable_value_t *v,
uintptr_t data);
static ngx_http_module_t ngx_http_backend_ssl_module_ctx = {
ngx_http_backend_ssl_add_variables, /* preconfiguration */
NULL, /* postconfiguration */
NULL, NULL, /* create/init main conf */
NULL, NULL, /* create/merge srv conf */
NULL, NULL /* create/merge loc conf */
};
ngx_module_t ngx_http_backend_ssl_module = {
NGX_MODULE_V1,
&ngx_http_backend_ssl_module_ctx,
NULL,
NGX_HTTP_MODULE,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NGX_MODULE_V1_PADDING
};
static ngx_int_t ngx_http_ssl_static_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
@ -89,6 +119,79 @@ static ngx_conf_enum_t ngx_http_ssl_ocsp[] = {
{ ngx_null_string, 0 }
};
static ngx_int_t
ngx_http_variable_backend_ssl_cipher(ngx_http_request_t *r,
ngx_http_variable_value_t *v,
uintptr_t data)
{
// You'll need to pull this from your SSL backend context
ngx_http_backend_ssl_ctx_t *ctx;
ctx = ngx_http_get_module_ctx(r, ngx_http_backend_ssl_module);
if (ctx == NULL || ctx->backend_ssl_cipher == NULL) {
v->not_found = 1;
return NGX_OK;
}
v->data = ctx->backend_ssl_cipher;
v->len = ngx_strlen(ctx->backend_ssl_cipher);
v->valid = 1;
v->no_cacheable = 0;
v->not_found = 0;
return NGX_OK;
}
static ngx_int_t
ngx_http_variable_backend_ssl_protocol(ngx_http_request_t *r,
ngx_http_variable_value_t *v,
uintptr_t data)
{
// You'll need to pull this from your SSL backend context
ngx_http_backend_ssl_ctx_t *ctx;
ctx = ngx_http_get_module_ctx(r, ngx_http_backend_ssl_module);
if (ctx == NULL || ctx->backend_ssl_protocol == NULL) {
v->not_found = 1;
return NGX_OK;
}
v->data = ctx->backend_ssl_protocol;
v->len = ngx_strlen(ctx->backend_ssl_protocol);
v->valid = 1;
v->no_cacheable = 0;
v->not_found = 0;
return NGX_OK;
}
// Add this function to register your custom variables
static ngx_int_t
ngx_http_backend_ssl_add_variables(ngx_conf_t *cf)
{
ngx_http_variable_t *var;
ngx_str_t name;
name.len = sizeof("backend_ssl_protocol") - 1;
name.data = (u_char *)"backend_ssl_protocol";
var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE);
if (var == NULL) {
return NGX_ERROR;
}
var->get_handler = ngx_http_variable_backend_ssl_protocol;
name.len = sizeof("backend_ssl_cipher") - 1;
name.data = (u_char *)"backend_ssl_cipher";
var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE);
if (var == NULL) {
return NGX_ERROR;
}
var->get_handler = ngx_http_variable_backend_ssl_cipher;
return NGX_OK;
}
static ngx_conf_post_t ngx_http_ssl_conf_command_post =
{ ngx_http_ssl_conf_command_check };
@ -302,6 +405,38 @@ static ngx_command_t ngx_http_ssl_commands[] = {
ngx_null_command
};
u_char *
ngx_ssl_get_backend_cipher(ngx_connection_t *c)
{
const SSL_CIPHER *cipher;
const char *name;
if (c == NULL || c->ssl == NULL || c->ssl->connection == NULL) {
return NULL;
}
cipher = SSL_get_current_cipher(c->ssl->connection);
if (cipher == NULL) {
return NULL;
}
name = SSL_CIPHER_get_name(cipher);
return (u_char *) name;
}
u_char *
ngx_ssl_get_backend_protocol(ngx_connection_t *c)
{
const char *proto;
if (c == NULL || c->ssl == NULL || c->ssl->connection == NULL) {
return NULL;
}
proto = SSL_get_version(c->ssl->connection);
return (u_char *) proto;
}
static ngx_http_module_t ngx_http_ssl_module_ctx = {
ngx_http_ssl_add_variables, /* preconfiguration */
@ -408,6 +543,13 @@ static ngx_http_variable_t ngx_http_ssl_vars[] = {
{ ngx_string("ssl_client_v_remain"), NULL, ngx_http_ssl_variable,
(uintptr_t) ngx_ssl_get_client_v_remain, NGX_HTTP_VAR_CHANGEABLE, 0 },
{ ngx_string("backend_ssl_protocol"), NULL,
ngx_http_variable_backend_ssl_protocol, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
{ ngx_string("backend_ssl_cipher"), NULL,
ngx_http_variable_backend_ssl_cipher, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
ngx_http_null_variable
};

View File

@ -13,6 +13,12 @@
#include <ngx_core.h>
#include <ngx_http.h>
typedef struct {
u_char *backend_ssl_protocol;
u_char *backend_ssl_cipher;
} ngx_http_backend_ssl_ctx_t;
extern ngx_module_t ngx_http_backend_ssl_module;
typedef struct {
ngx_ssl_t ssl;

View File

@ -323,7 +323,8 @@ typedef struct {
ngx_http_regex_t *ssl_servername_regex;
#endif
#endif
u_char *backend_ssl_protocol;
u_char *backend_ssl_cipher;
ngx_chain_t *busy;
ngx_int_t nbusy;

View File

@ -8,7 +8,7 @@
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
#include "ngx_http_ssl_module.h"
#if (NGX_HTTP_CACHE)
static ngx_int_t ngx_http_upstream_cache(ngx_http_request_t *r,
@ -2563,8 +2563,28 @@ ngx_http_upstream_process_header(ngx_http_request_t *r, ngx_http_upstream_t *u)
return;
}
ngx_http_upstream_send_response(r, u);
if (u->peer.connection && u->peer.connection->ssl && u->peer.connection->ssl->connection) {
SSL *ssl_conn = u->peer.connection->ssl->connection;
ngx_http_backend_ssl_ctx_t *ctx = ngx_http_get_module_ctx(r, ngx_http_backend_ssl_module);
if (ctx == NULL) {
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_backend_ssl_ctx_t));
if (ctx == NULL) {
ngx_http_upstream_finalize_request(r, u, NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
ngx_http_set_ctx(r, ctx, ngx_http_backend_ssl_module);
}
const char *proto = SSL_get_version(ssl_conn);
const char *cipher = SSL_get_cipher_name(ssl_conn);
ctx->backend_ssl_protocol = (u_char *) (proto ? proto : "unknown");
ctx->backend_ssl_cipher = (u_char *) (cipher ? cipher : "unknown");
}
ngx_http_upstream_send_response(r, u);
}
static ngx_int_t

View File

@ -4,13 +4,11 @@
* Copyright (C) Nginx, Inc.
*/
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
#include <nginx.h>
static ngx_http_variable_t *ngx_http_add_prefix_variable(ngx_conf_t *cf,
ngx_str_t *name, ngx_uint_t flags);
@ -131,7 +129,6 @@ static ngx_int_t ngx_http_variable_connection_requests(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_connection_time(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_nginx_version(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_hostname(ngx_http_request_t *r,
@ -1030,7 +1027,6 @@ ngx_http_variable_unknown_header(ngx_http_request_t *r,
return NGX_OK;
}
static ngx_int_t
ngx_http_variable_request_line(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
@ -1549,7 +1545,6 @@ ngx_http_variable_set_args(ngx_http_request_t *r,
r->valid_unparsed_uri = 0;
}
static ngx_int_t
ngx_http_variable_is_args(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)