mirror of
https://github.com/nginx/nginx.git
synced 2025-07-20 19:27:29 +08:00
Add custom SSL/TLS handling in upstream logic
This commit is contained in:
parent
5b8a5c08ce
commit
711e66b411
@ -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 */
|
||||
@ -406,7 +541,14 @@ static ngx_http_variable_t ngx_http_ssl_vars[] = {
|
||||
(uintptr_t) ngx_ssl_get_client_v_end, NGX_HTTP_VAR_CHANGEABLE, 0 },
|
||||
|
||||
{ ngx_string("ssl_client_v_remain"), NULL, ngx_http_ssl_variable,
|
||||
(uintptr_t) ngx_ssl_get_client_v_remain, NGX_HTTP_VAR_CHANGEABLE, 0 },
|
||||
(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
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
@ -7055,4 +7075,4 @@ ngx_http_upstream_init_main_conf(ngx_conf_t *cf, void *conf)
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
}
|
@ -452,4 +452,4 @@ extern ngx_conf_bitmask_t ngx_http_upstream_cache_method_mask[];
|
||||
extern ngx_conf_bitmask_t ngx_http_upstream_ignore_headers_masks[];
|
||||
|
||||
|
||||
#endif /* _NGX_HTTP_UPSTREAM_H_INCLUDED_ */
|
||||
#endif /* _NGX_HTTP_UPSTREAM_H_INCLUDED_ */
|
@ -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,
|
||||
@ -165,7 +162,7 @@ static ngx_http_variable_t ngx_http_core_variables[] = {
|
||||
|
||||
{ ngx_string("http_host"), NULL, ngx_http_variable_header,
|
||||
offsetof(ngx_http_request_t, headers_in.host), 0, 0 },
|
||||
|
||||
|
||||
{ ngx_string("http_user_agent"), NULL, ngx_http_variable_header,
|
||||
offsetof(ngx_http_request_t, headers_in.user_agent), 0, 0 },
|
||||
|
||||
@ -397,7 +394,7 @@ static ngx_http_variable_t ngx_http_core_variables[] = {
|
||||
|
||||
{ ngx_string("arg_"), NULL, ngx_http_variable_argument,
|
||||
0, NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_PREFIX, 0 },
|
||||
|
||||
|
||||
ngx_http_null_variable
|
||||
};
|
||||
|
||||
@ -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)
|
||||
@ -2832,4 +2827,4 @@ ngx_http_variables_init_vars(ngx_conf_t *cf)
|
||||
cmcf->variables_keys = NULL;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user