[PATCH] Proxy SSL Verify

Maxim Dounin mdounin at mdounin.ru
Wed Sep 14 00:17:49 UTC 2011


Hello!

On Tue, Sep 13, 2011 at 02:44:48PM -0700, W. Andrew Loe III wrote:

> This patch allows you to force OpenSSL to validate the certificate of
> the server the http_proxy module is communicating with. Originally
> built against 0.7.x branch, I will forward port when I can. I would
> appreciate if anyone else has input on how to do this more elegantly,
> my skills are rudimentary at best.
> 
> 
> diff -uNr ../nginx-0.7.67/src/event/ngx_event_openssl.c
> src/event/ngx_event_openssl.c
> --- ../nginx-0.7.67/src/event/ngx_event_openssl.c	2010-06-07
> 04:55:20.000000000 -0700
> +++ src/event/ngx_event_openssl.c	2011-09-13 14:17:05.000000000 -0700
> @@ -157,6 +157,12 @@
>      SSL_CTX_set_options(ssl->ctx, SSL_OP_NETSCAPE_CHALLENGE_BUG);
>      SSL_CTX_set_options(ssl->ctx, SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG);
> 
> +    /* verification options */
> +
> +    SSL_CTX_load_verify_locations(ssl->ctx, (const char
> *)ssl->ca_certificate.data, NULL);
> +    SSL_CTX_set_verify(ssl->ctx, ssl->verify, NULL);
> +    SSL_CTX_set_verify_depth(ssl->ctx, ssl->verify_depth);
> +

This should be done in separate function, similar to 
ngx_ssl_client_certificate() (actually, subset of it).  And with 
appropriate error checking.

>      /* server side options */
> 
>      SSL_CTX_set_options(ssl->ctx, SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG);
> diff -uNr ../nginx-0.7.67/src/event/ngx_event_openssl.h
> src/event/ngx_event_openssl.h
> --- ../nginx-0.7.67/src/event/ngx_event_openssl.h	2010-06-07
> 03:09:14.000000000 -0700
> +++ src/event/ngx_event_openssl.h	2011-09-13 14:17:05.000000000 -0700
> @@ -27,6 +27,9 @@
>  typedef struct {
>      SSL_CTX                    *ctx;
>      ngx_log_t                  *log;
> +    ngx_uint_t                  verify;
> +    ngx_uint_t                  verify_depth;
> +    ngx_str_t                   ca_certificate;
>  } ngx_ssl_t;

This shouldn't be here at all.

> 
> 
> diff -uNr ../nginx-0.7.67/src/http/modules/ngx_http_proxy_module.c
> src/http/modules/ngx_http_proxy_module.c
> --- ../nginx-0.7.67/src/http/modules/ngx_http_proxy_module.c	2010-06-07
> 05:23:23.000000000 -0700
> +++ src/http/modules/ngx_http_proxy_module.c	2011-09-13 14:17:05.000000000 -0700
> @@ -466,6 +466,27 @@
>        offsetof(ngx_http_proxy_loc_conf_t, upstream.ssl_session_reuse),
>        NULL },
> 
> +      { ngx_string("proxy_ssl_verify"),
> +      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
> +      ngx_conf_set_num_slot,
> +      NGX_HTTP_LOC_CONF_OFFSET,
> +      offsetof(ngx_http_proxy_loc_conf_t, upstream.ssl_verify),
> +      NULL },

You don't want to let users to control binary arguments passed to 
openssl.

It should be either on/off switch (flag slot), or should go away 
completely, switched on by certificate file presense.

If it stays, it probably should be named as 
"proxy_ssl_verify_peer" to be in line with "ssl_verify_client" 
directive (and see below).

> +
> +      { ngx_string("proxy_ssl_verify_depth"),
> +      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
> +      ngx_conf_set_num_slot,
> +      NGX_HTTP_LOC_CONF_OFFSET,
> +      offsetof(ngx_http_proxy_loc_conf_t, upstream.ssl_verify_depth),
> +      NULL },
> +
> +      { ngx_string("proxy_ssl_ca_certificate"),

Probably "proxy_ssl_peer_certificate" would be a better directive 
name.  Not sure.

> +      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
> +      ngx_conf_set_str_slot,
> +      NGX_HTTP_LOC_CONF_OFFSET,
> +      offsetof(ngx_http_proxy_loc_conf_t, upstream.ssl_ca_certificate),
> +      NULL },
> +
>  #endif
> 
>        ngx_null_command
> @@ -1950,6 +1971,8 @@
>      conf->upstream.intercept_errors = NGX_CONF_UNSET;
>  #if (NGX_HTTP_SSL)
>      conf->upstream.ssl_session_reuse = NGX_CONF_UNSET;
> +    conf->upstream.ssl_verify = NGX_CONF_UNSET_UINT;
> +    conf->upstream.ssl_verify_depth = NGX_CONF_UNSET_UINT;
>  #endif
> 
>      /* "proxy_cyclic_temp_file" is disabled */
> @@ -2196,6 +2219,22 @@
>  #if (NGX_HTTP_SSL)
>      ngx_conf_merge_value(conf->upstream.ssl_session_reuse,
>                                prev->upstream.ssl_session_reuse, 1);
> +    ngx_conf_merge_uint_value(conf->upstream.ssl_verify,
> +                              prev->upstream.ssl_verify, 0);
> +    ngx_conf_merge_uint_value(conf->upstream.ssl_verify_depth,
> +                              prev->upstream.ssl_verify_depth, 1);
> +    ngx_conf_merge_str_value(conf->upstream.ssl_ca_certificate,
> +                              prev->upstream.ssl_ca_certificate, "");
> +
> +    if (conf->upstream.ssl_verify) {
> +      if (conf->upstream.ssl_ca_certificate.len == 0) {
> +        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
> +            "no \"proxy_ssl_ca_certificate\" is defined for "
> +            "the \"proxy_ssl_verify\" directive");
> +
> +        return NGX_CONF_ERROR;
> +      }

No 2-space indentation, please.

> +    }
>  #endif
> 
>      ngx_conf_merge_value(conf->redirect, prev->redirect, 1);
> @@ -3011,6 +3050,12 @@
> 
>      plcf->upstream.ssl->log = cf->log;
> 
> +    plcf->upstream.ssl->ca_certificate.len =
> plcf->upstream.ssl_ca_certificate.len;
> +    plcf->upstream.ssl->ca_certificate.data =
> plcf->upstream.ssl_ca_certificate.data;
> +
> +    plcf->upstream.ssl->verify = plcf->upstream.ssl_verify;
> +    plcf->upstream.ssl->verify_depth = plcf->upstream.ssl_verify_depth;
> +
>      if (ngx_ssl_create(plcf->upstream.ssl,
>                         NGX_SSL_SSLv2|NGX_SSL_SSLv3|NGX_SSL_TLSv1, NULL)
>          != NGX_OK)
> diff -uNr ../nginx-0.7.67/src/http/ngx_http_upstream.h
> src/http/ngx_http_upstream.h
> --- ../nginx-0.7.67/src/http/ngx_http_upstream.h	2010-06-07
> 05:23:23.000000000 -0700
> +++ src/http/ngx_http_upstream.h	2011-09-13 14:17:05.000000000 -0700
> @@ -173,6 +173,9 @@
>  #if (NGX_HTTP_SSL)
>      ngx_ssl_t                       *ssl;
>      ngx_flag_t                       ssl_session_reuse;
> +    ngx_uint_t                       ssl_verify;
> +    ngx_uint_t                       ssl_verify_depth;
> +    ngx_str_t                        ssl_ca_certificate;
>  #endif
> 
>  } ngx_http_upstream_conf_t;

You may also want to add "proxy_ssl_crl" directive (trivial), as 
well as some form of remote CN checking.

Please also note that posting patches against 0.7.* (as well as 
0.8.*), isn't meaningful.  Development branch is 1.1.*.

Maxim Dounin



More information about the nginx-devel mailing list