对于sni的基础知识,就不再多少了,自己google去.
使用openssl,客户端 ,在初始化SSL connection之前,调用SSL_set_tlsext_host_name(ssl, servername).
对于服务器端
每一个证书,都要调用SSL_CTX(),
在SSL_CTX()中调用SSL_CTX_set_tlsext_servername_callback()函数
在回调函数中,使用SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name),得到hostname
openssl 源码目录apps/s_client.c 和s_server.c 是最好的例子.
可以使用命令行 servername 设置 TLS extension servername
openssl s_client -connect myweb.address.com:443 -servername myweb.address.com
openssl s_server -accept 443 -cert normal_cert.pem -key normal_key.ky -servername xyz.com -cert2 sni_cert.pem -key2 sni_key.ky
也可以不用域名
openssl s_client -servername xyz.com -connect ip:port
在nginx源码目录 src/http/modules/ngx_http_ssl_module.c
-
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
-
-
if (SSL_CTX_set_tlsext_servername_callback(conf->ssl.ctx,
-
ngx_http_ssl_servername)
-
== 0)
-
{
-
ngx_log_error(NGX_LOG_WARN, cf->log, 0,
-
"nginx was built with SNI support, however, now it is linked "
-
"dynamically to an OpenSSL library which has no tlsext support, "
-
"therefore SNI is not available");
-
}
-
-
#endif
其中ngx_http_ssl_servername在src/http/ngx_http_request.c中定义
-
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
-
-
int
-
ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
-
{
-
ngx_str_t host;
-
const char *servername;
-
ngx_connection_t *c;
-
ngx_http_connection_t *hc;
-
ngx_http_ssl_srv_conf_t *sscf;
-
ngx_http_core_loc_conf_t *clcf;
-
ngx_http_core_srv_conf_t *cscf;
-
-
servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);
-
-
if (servername == NULL) {
-
return SSL_TLSEXT_ERR_NOACK;
-
}
-
-
c = ngx_ssl_get_connection(ssl_conn);
-
-
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
-
"SSL server name: \"%s\"", servername);
-
-
host.len = ngx_strlen(servername);
-
-
if (host.len == 0) {
-
return SSL_TLSEXT_ERR_NOACK;
-
}
-
-
host.data = (u_char *) servername;
-
-
if (ngx_http_validate_host(&host, c->pool, 1) != NGX_OK) {
-
return SSL_TLSEXT_ERR_NOACK;
-
}
-
-
hc = c->data;
-
-
if (ngx_http_find_virtual_server(c, hc->addr_conf->virtual_names, &host,
-
NULL, &cscf)
-
!= NGX_OK)
-
{
-
return SSL_TLSEXT_ERR_NOACK;
-
}
-
-
hc->ssl_servername = ngx_palloc(c->pool, sizeof(ngx_str_t));
-
if (hc->ssl_servername == NULL) {
-
return SSL_TLSEXT_ERR_NOACK;
-
}
-
-
*hc->ssl_servername = host;
-
-
hc->conf_ctx = cscf->ctx;
-
-
clcf = ngx_http_get_module_loc_conf(hc->conf_ctx, ngx_http_core_module);
-
-
ngx_http_set_connection_log(c, clcf->error_log);
-
-
sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module);
-
-
if (sscf->ssl.ctx) {
-
SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx);
-
-
/*
-
* SSL_set_SSL_CTX() only changes certs as of 1.0.0d
-
* adjust other things we care about
-
*/
-
-
SSL_set_verify(ssl_conn, SSL_CTX_get_verify_mode(sscf->ssl.ctx),
-
SSL_CTX_get_verify_callback(sscf->ssl.ctx));
-
-
SSL_set_verify_depth(ssl_conn, SSL_CTX_get_verify_depth(sscf->ssl.ctx));
-
-
#ifdef SSL_CTRL_CLEAR_OPTIONS
-
/* only in 0.9.8m+ */
-
SSL_clear_options(ssl_conn, SSL_get_options(ssl_conn) &
-
~SSL_CTX_get_options(sscf->ssl.ctx));
-
#endif
-
-
SSL_set_options(ssl_conn, SSL_CTX_get_options(sscf->ssl.ctx));
-
}
-
-
return SSL_TLSEXT_ERR_OK;
-
}
-
-
#endif
阅读(3305) | 评论(0) | 转发(0) |