]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
AST-2016-001 http: Provide greater control of TLS and set modern defaults. 64/2164/3
authorJoshua Colp <jcolp@digium.com>
Wed, 3 Feb 2016 18:05:52 +0000 (14:05 -0400)
committerKevin Harwell <kharwell@digium.com>
Wed, 3 Feb 2016 21:10:59 +0000 (15:10 -0600)
This change exposes the configuration of various aspects of the TLS
support and sets the default to the modern standards.

The TLS cipher is now set to the best values according to the
Mozilla OpSec team, different TLS versions can now be disabled, and
the cipher order can be forced to be that of the server instead of
the client.

ASTERISK-24972 #close

Change-Id: I8635470e722ce6d47951a5045ae9ef348271d395

configs/samples/http.conf.sample
include/asterisk/tcptls.h
main/http.c
main/tcptls.c

index 44095a11e9aa241ec420ac412b6112a096884492..f6dd64ed31cadf9fcf5a346c1f8de07b978afce6 100644 (file)
@@ -80,6 +80,26 @@ bindaddr=127.0.0.1
 ; private in same .pem file.
 ; openssl req -new -x509 -days 365 -nodes -out /tmp/foo.pem -keyout /tmp/foo.pem
 ;
+; tlscipher=                             ; The list of allowed ciphers
+;                                        ; if none are specified the following cipher
+;                                        ; list will be used instead:
+; ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:
+; ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:
+; kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:
+; ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:
+; ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:
+; DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:
+; AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:
+; AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:
+; !EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
+;
+; tlsdisablev1=yes                ; Disable TLSv1 support - if not set this defaults to "yes"
+; tlsdisablev11=yes               ; Disable TLSv1.1 support - if not set this defaults to "no"
+; tlsdisablev12=yes               ; Disable TLSv1.2 support - if not set this defaults to "no"
+;
+; tlsservercipherorder=yes        ; Use the server preference order instead of the client order
+;                                 ; Defaults to "yes"
+;
 ; The post_mappings section maps URLs to real paths on the filesystem.  If a
 ; POST is done from within an authenticated manager session to one of the
 ; configured POST mappings, then any files in the POST will be placed in the
index 0e8d9d042fd57a17b49c934c83222932bbcdcee9..e1a632cca4273ad9bf1456d7759eb987175e8b8e 100644 (file)
@@ -86,7 +86,15 @@ enum ast_ssl_flags {
        /*! Use SSLv3 for outgoing client connections */
        AST_SSL_SSLV3_CLIENT = (1 << 4),
        /*! Use TLSv1 for outgoing client connections */
-       AST_SSL_TLSV1_CLIENT = (1 << 5)
+       AST_SSL_TLSV1_CLIENT = (1 << 5),
+       /*! Use server cipher order instead of the client order */
+       AST_SSL_SERVER_CIPHER_ORDER = (1 << 6),
+       /*! Disable TLSv1 support */
+       AST_SSL_DISABLE_TLSV1 = (1 << 7),
+       /*! Disable TLSv1.1 support */
+       AST_SSL_DISABLE_TLSV11 = (1 << 8),
+       /*! Disable TLSv1.2 support */
+       AST_SSL_DISABLE_TLSV12 = (1 << 9),
 };
 
 struct ast_tls_config {
index 5363a154ad3cc3ff7a33229372de71e9618b6bf3..993488a49a0b6767c17d3b47996b19dcd150318a 100644 (file)
@@ -2059,10 +2059,13 @@ static int __ast_http_load(int reload)
        }
        http_tls_cfg.pvtfile = ast_strdup("");
 
+       /* Apply modern intermediate settings according to the Mozilla OpSec team as of July 30th, 2015 but disable TLSv1 */
+       ast_set_flag(&http_tls_cfg.flags, AST_SSL_DISABLE_TLSV1 | AST_SSL_SERVER_CIPHER_ORDER);
+
        if (http_tls_cfg.cipher) {
                ast_free(http_tls_cfg.cipher);
        }
-       http_tls_cfg.cipher = ast_strdup("");
+       http_tls_cfg.cipher = ast_strdup("ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA");
 
        AST_RWLIST_WRLOCK(&uri_redirects);
        while ((redirect = AST_RWLIST_REMOVE_HEAD(&uri_redirects, entry))) {
@@ -2086,8 +2089,6 @@ static int __ast_http_load(int reload)
                        && strcasecmp(v->name, "tlsdontverifyserver")
                        && strcasecmp(v->name, "tlsclientmethod")
                        && strcasecmp(v->name, "sslclientmethod")
-                       && strcasecmp(v->name, "tlscipher")
-                       && strcasecmp(v->name, "sslcipher")
                        && !ast_tls_read_conf(&http_tls_cfg, &https_desc, v->name, v->value)) {
                        continue;
                }
index f462c65f7d130fcb37ed596fe0f6df1da25e3d65..2f5191202ba474ba4d5a1379ee518e2e9a001452 100644 (file)
@@ -755,7 +755,8 @@ static int __ssl_setup(struct ast_tls_config *cfg, int client)
        return 0;
 #else
        int disable_ssl = 0;
+       long ssl_opts = 0;
+
        if (!cfg->enabled) {
                return 0;
        }
@@ -800,11 +801,24 @@ static int __ssl_setup(struct ast_tls_config *cfg, int client)
         * them. SSLv23_*_method supports TLSv1+.
         */
        if (disable_ssl) {
-               long ssl_opts;
+               ssl_opts |= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
+       }
+
+       if (ast_test_flag(&cfg->flags, AST_SSL_SERVER_CIPHER_ORDER)) {
+               ssl_opts |= SSL_OP_CIPHER_SERVER_PREFERENCE;
+       }
 
-               ssl_opts = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
-               SSL_CTX_set_options(cfg->ssl_ctx, ssl_opts);
+       if (ast_test_flag(&cfg->flags, AST_SSL_DISABLE_TLSV1)) {
+               ssl_opts |= SSL_OP_NO_TLSv1;
        }
+       if (ast_test_flag(&cfg->flags, AST_SSL_DISABLE_TLSV11)) {
+               ssl_opts |= SSL_OP_NO_TLSv1_1;
+       }
+       if (ast_test_flag(&cfg->flags, AST_SSL_DISABLE_TLSV12)) {
+               ssl_opts |= SSL_OP_NO_TLSv1_2;
+       }
+
+       SSL_CTX_set_options(cfg->ssl_ctx, ssl_opts);
 
        SSL_CTX_set_verify(cfg->ssl_ctx,
                ast_test_flag(&cfg->flags, AST_SSL_VERIFY_CLIENT) ? SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT : SSL_VERIFY_NONE,
@@ -1157,6 +1171,14 @@ int ast_tls_read_conf(struct ast_tls_config *tls_cfg, struct ast_tcptls_session_
                        ast_clear_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT);
                        ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV3_CLIENT);
                }
+       } else if (!strcasecmp(varname, "tlsservercipherorder")) {
+               ast_set2_flag(&tls_cfg->flags, ast_true(value), AST_SSL_SERVER_CIPHER_ORDER);
+       } else if (!strcasecmp(varname, "tlsdisablev1")) {
+               ast_set2_flag(&tls_cfg->flags, ast_true(value), AST_SSL_DISABLE_TLSV1);
+       } else if (!strcasecmp(varname, "tlsdisablev11")) {
+               ast_set2_flag(&tls_cfg->flags, ast_true(value), AST_SSL_DISABLE_TLSV11);
+       } else if (!strcasecmp(varname, "tlsdisablev12")) {
+               ast_set2_flag(&tls_cfg->flags, ast_true(value), AST_SSL_DISABLE_TLSV12);
        } else {
                return -1;
        }