Mercurial > hg > nginx-quic
comparison src/http/modules/ngx_http_ssl_module.c @ 8185:59e1c73fe02b
SSL: ssl_reject_handshake directive (ticket #195).
In some cases it might be needed to reject SSL handshake based on SNI
server name provided, for example, to make sure an invalid certificate
is not returned to clients trying to contact a name-based virtual server
without SSL configured. Previously, a "ssl_ciphers aNULL;" was used for
this. This workaround, however, is not compatible with TLSv1.3, in
particular, when using BoringSSL, where it is not possible to configure
TLSv1.3 ciphers at all.
With this change, the ssl_reject_handshake directive is introduced,
which instructs nginx to reject SSL handshakes with an "unrecognized_name"
alert in a particular server block.
For example, to reject handshake with names other than example.com,
one can use the following configuration:
server {
listen 443 ssl;
ssl_reject_handshake on;
}
server {
listen 443 ssl;
server_name example.com;
ssl_certificate example.com.crt;
ssl_certificate_key example.com.key;
}
The following configuration can be used to reject all SSL handshakes
without SNI server name provided:
server {
listen 443 ssl;
ssl_reject_handshake on;
}
server {
listen 443 ssl;
server_name ~^;
ssl_certificate example.crt;
ssl_certificate_key example.key;
}
Additionally, the ssl_reject_handshake directive makes configuring
certificates for the default server block optional. If no certificates
are configured in the default server for a given listening socket,
certificates must be defined in all non-default server blocks with
the listening socket in question.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 22 Oct 2020 18:02:28 +0300 |
parents | 3bff3f397c05 |
children | 71b7453fb11f 7ce28b4cc57e |
comparison
equal
deleted
inserted
replaced
8184:fd0b2226919b | 8185:59e1c73fe02b |
---|---|
291 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE2, | 291 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE2, |
292 ngx_conf_set_keyval_slot, | 292 ngx_conf_set_keyval_slot, |
293 NGX_HTTP_SRV_CONF_OFFSET, | 293 NGX_HTTP_SRV_CONF_OFFSET, |
294 offsetof(ngx_http_ssl_srv_conf_t, conf_commands), | 294 offsetof(ngx_http_ssl_srv_conf_t, conf_commands), |
295 &ngx_http_ssl_conf_command_post }, | 295 &ngx_http_ssl_conf_command_post }, |
296 | |
297 { ngx_string("ssl_reject_handshake"), | |
298 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG, | |
299 ngx_conf_set_flag_slot, | |
300 NGX_HTTP_SRV_CONF_OFFSET, | |
301 offsetof(ngx_http_ssl_srv_conf_t, reject_handshake), | |
302 NULL }, | |
296 | 303 |
297 ngx_null_command | 304 ngx_null_command |
298 }; | 305 }; |
299 | 306 |
300 | 307 |
612 */ | 619 */ |
613 | 620 |
614 sscf->enable = NGX_CONF_UNSET; | 621 sscf->enable = NGX_CONF_UNSET; |
615 sscf->prefer_server_ciphers = NGX_CONF_UNSET; | 622 sscf->prefer_server_ciphers = NGX_CONF_UNSET; |
616 sscf->early_data = NGX_CONF_UNSET; | 623 sscf->early_data = NGX_CONF_UNSET; |
624 sscf->reject_handshake = NGX_CONF_UNSET; | |
617 sscf->buffer_size = NGX_CONF_UNSET_SIZE; | 625 sscf->buffer_size = NGX_CONF_UNSET_SIZE; |
618 sscf->verify = NGX_CONF_UNSET_UINT; | 626 sscf->verify = NGX_CONF_UNSET_UINT; |
619 sscf->verify_depth = NGX_CONF_UNSET_UINT; | 627 sscf->verify_depth = NGX_CONF_UNSET_UINT; |
620 sscf->certificates = NGX_CONF_UNSET_PTR; | 628 sscf->certificates = NGX_CONF_UNSET_PTR; |
621 sscf->certificate_keys = NGX_CONF_UNSET_PTR; | 629 sscf->certificate_keys = NGX_CONF_UNSET_PTR; |
658 | 666 |
659 ngx_conf_merge_value(conf->prefer_server_ciphers, | 667 ngx_conf_merge_value(conf->prefer_server_ciphers, |
660 prev->prefer_server_ciphers, 0); | 668 prev->prefer_server_ciphers, 0); |
661 | 669 |
662 ngx_conf_merge_value(conf->early_data, prev->early_data, 0); | 670 ngx_conf_merge_value(conf->early_data, prev->early_data, 0); |
671 ngx_conf_merge_value(conf->reject_handshake, prev->reject_handshake, 0); | |
663 | 672 |
664 ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols, | 673 ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols, |
665 (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1 | 674 (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1 |
666 |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2)); | 675 |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2)); |
667 | 676 |
705 | 714 |
706 conf->ssl.log = cf->log; | 715 conf->ssl.log = cf->log; |
707 | 716 |
708 if (conf->enable) { | 717 if (conf->enable) { |
709 | 718 |
710 if (conf->certificates == NULL) { | 719 if (conf->certificates) { |
720 if (conf->certificate_keys == NULL) { | |
721 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
722 "no \"ssl_certificate_key\" is defined for " | |
723 "the \"ssl\" directive in %s:%ui", | |
724 conf->file, conf->line); | |
725 return NGX_CONF_ERROR; | |
726 } | |
727 | |
728 if (conf->certificate_keys->nelts < conf->certificates->nelts) { | |
729 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
730 "no \"ssl_certificate_key\" is defined " | |
731 "for certificate \"%V\" and " | |
732 "the \"ssl\" directive in %s:%ui", | |
733 ((ngx_str_t *) conf->certificates->elts) | |
734 + conf->certificates->nelts - 1, | |
735 conf->file, conf->line); | |
736 return NGX_CONF_ERROR; | |
737 } | |
738 | |
739 } else if (!conf->reject_handshake) { | |
711 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | 740 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, |
712 "no \"ssl_certificate\" is defined for " | 741 "no \"ssl_certificate\" is defined for " |
713 "the \"ssl\" directive in %s:%ui", | 742 "the \"ssl\" directive in %s:%ui", |
714 conf->file, conf->line); | 743 conf->file, conf->line); |
715 return NGX_CONF_ERROR; | 744 return NGX_CONF_ERROR; |
716 } | 745 } |
717 | 746 |
718 if (conf->certificate_keys == NULL) { | 747 } else if (conf->certificates) { |
719 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
720 "no \"ssl_certificate_key\" is defined for " | |
721 "the \"ssl\" directive in %s:%ui", | |
722 conf->file, conf->line); | |
723 return NGX_CONF_ERROR; | |
724 } | |
725 | |
726 if (conf->certificate_keys->nelts < conf->certificates->nelts) { | |
727 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
728 "no \"ssl_certificate_key\" is defined " | |
729 "for certificate \"%V\" and " | |
730 "the \"ssl\" directive in %s:%ui", | |
731 ((ngx_str_t *) conf->certificates->elts) | |
732 + conf->certificates->nelts - 1, | |
733 conf->file, conf->line); | |
734 return NGX_CONF_ERROR; | |
735 } | |
736 | |
737 } else { | |
738 | |
739 if (conf->certificates == NULL) { | |
740 return NGX_CONF_OK; | |
741 } | |
742 | 748 |
743 if (conf->certificate_keys == NULL | 749 if (conf->certificate_keys == NULL |
744 || conf->certificate_keys->nelts < conf->certificates->nelts) | 750 || conf->certificate_keys->nelts < conf->certificates->nelts) |
745 { | 751 { |
746 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | 752 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, |
748 "for certificate \"%V\"", | 754 "for certificate \"%V\"", |
749 ((ngx_str_t *) conf->certificates->elts) | 755 ((ngx_str_t *) conf->certificates->elts) |
750 + conf->certificates->nelts - 1); | 756 + conf->certificates->nelts - 1); |
751 return NGX_CONF_ERROR; | 757 return NGX_CONF_ERROR; |
752 } | 758 } |
759 | |
760 } else if (!conf->reject_handshake) { | |
761 return NGX_CONF_OK; | |
753 } | 762 } |
754 | 763 |
755 if (ngx_ssl_create(&conf->ssl, conf->protocols, conf) != NGX_OK) { | 764 if (ngx_ssl_create(&conf->ssl, conf->protocols, conf) != NGX_OK) { |
756 return NGX_CONF_ERROR; | 765 return NGX_CONF_ERROR; |
757 } | 766 } |
806 "\"ssl_certificate\" and \"ssl_certificate_key\" " | 815 "\"ssl_certificate\" and \"ssl_certificate_key\" " |
807 "directives are not supported on this platform"); | 816 "directives are not supported on this platform"); |
808 return NGX_CONF_ERROR; | 817 return NGX_CONF_ERROR; |
809 #endif | 818 #endif |
810 | 819 |
811 } else { | 820 } else if (conf->certificates) { |
812 | 821 |
813 /* configure certificates */ | 822 /* configure certificates */ |
814 | 823 |
815 if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, | 824 if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, |
816 conf->certificate_keys, conf->passwords) | 825 conf->certificate_keys, conf->passwords) |
944 { | 953 { |
945 ngx_str_t *cert, *key; | 954 ngx_str_t *cert, *key; |
946 ngx_uint_t i, nelts; | 955 ngx_uint_t i, nelts; |
947 ngx_http_complex_value_t *cv; | 956 ngx_http_complex_value_t *cv; |
948 ngx_http_compile_complex_value_t ccv; | 957 ngx_http_compile_complex_value_t ccv; |
958 | |
959 if (conf->certificates == NULL) { | |
960 return NGX_OK; | |
961 } | |
949 | 962 |
950 cert = conf->certificates->elts; | 963 cert = conf->certificates->elts; |
951 key = conf->certificate_keys->elts; | 964 key = conf->certificate_keys->elts; |
952 nelts = conf->certificates->nelts; | 965 nelts = conf->certificates->nelts; |
953 | 966 |
1325 } | 1338 } |
1326 | 1339 |
1327 cscf = addr[a].default_server; | 1340 cscf = addr[a].default_server; |
1328 sscf = cscf->ctx->srv_conf[ngx_http_ssl_module.ctx_index]; | 1341 sscf = cscf->ctx->srv_conf[ngx_http_ssl_module.ctx_index]; |
1329 | 1342 |
1330 if (sscf->certificates == NULL) { | 1343 if (sscf->certificates) { |
1344 continue; | |
1345 } | |
1346 | |
1347 if (!sscf->reject_handshake) { | |
1331 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | 1348 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, |
1332 "no \"ssl_certificate\" is defined for " | 1349 "no \"ssl_certificate\" is defined for " |
1333 "the \"listen ... ssl\" directive in %s:%ui", | 1350 "the \"listen ... ssl\" directive in %s:%ui", |
1334 cscf->file_name, cscf->line); | 1351 cscf->file_name, cscf->line); |
1335 return NGX_ERROR; | 1352 return NGX_ERROR; |
1336 } | 1353 } |
1354 | |
1355 /* | |
1356 * if no certificates are defined in the default server, | |
1357 * check all non-default server blocks | |
1358 */ | |
1359 | |
1360 cscfp = addr[a].servers.elts; | |
1361 for (s = 0; s < addr[a].servers.nelts; s++) { | |
1362 | |
1363 cscf = cscfp[s]; | |
1364 sscf = cscf->ctx->srv_conf[ngx_http_ssl_module.ctx_index]; | |
1365 | |
1366 if (sscf->certificates || sscf->reject_handshake) { | |
1367 continue; | |
1368 } | |
1369 | |
1370 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
1371 "no \"ssl_certificate\" is defined for " | |
1372 "the \"listen ... ssl\" directive in %s:%ui", | |
1373 cscf->file_name, cscf->line); | |
1374 return NGX_ERROR; | |
1375 } | |
1337 } | 1376 } |
1338 } | 1377 } |
1339 | 1378 |
1340 return NGX_OK; | 1379 return NGX_OK; |
1341 } | 1380 } |