Extend TLS Support (#8505)

* tls13: This commit brings TLS 1.3 to Netdata

* tls13: Update variables on slave side

* tls13: Fix compilation error for old libraries

* tls13: Fix compilation error for old libraries 2

* tls13 remove ciphers

* tls13: TLS versions

This commit brings the missing tls versions accpeted for Netdata
and it also brings documentation update related to these versions

* tls13: Remove dupplication

This commit removes wrong dupplication of code

* tls13: Documentation

This commit brings fix for the documentation

* tls13: Remove magic number

This commit removes the magic number to allow the code to be readable

* tls13: TLS version

Small adjust with TLS version

* tls13: Security Init

This commit removes array from the function and overwrite the magic number
with a string

* tls13: Remove new variable name from stream

* tls13: OpenSSL versions and old key name

This commit removes the new key names and also update the names
used to define openssl version
This commit is contained in:
thiagoftsm 2020-03-31 22:53:32 +00:00 committed by GitHub
parent 905a2dd54e
commit a12d4e56d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 81 additions and 28 deletions

View File

@ -406,6 +406,9 @@ static void security_init(){
snprintfz(filename, FILENAME_MAX, "%s/ssl/cert.pem",netdata_configured_user_config_dir);
security_cert = config_get(CONFIG_SECTION_WEB, "ssl certificate", filename);
tls_version = config_get(CONFIG_SECTION_WEB, "tls version", "1.3");
tls_ciphers = config_get(CONFIG_SECTION_WEB, "tls ciphers", "none");
security_openssl_library();
}
#endif

View File

@ -7,6 +7,8 @@ SSL_CTX *netdata_client_ctx=NULL;
SSL_CTX *netdata_srv_ctx=NULL;
const char *security_key=NULL;
const char *security_cert=NULL;
const char *tls_version=NULL;
const char *tls_ciphers=NULL;
int netdata_validate_server = NETDATA_SSL_VALID_CERTIFICATE;
/**
@ -32,14 +34,12 @@ static void security_info_callback(const SSL *ssl, int where, int ret __maybe_un
*/
void security_openssl_library()
{
#if OPENSSL_VERSION_NUMBER < 0x10100000L
# if (SSLEAY_VERSION_NUMBER >= 0x0907000L)
#if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_110
# if (SSLEAY_VERSION_NUMBER >= OPENSSL_VERSION_097)
OPENSSL_config(NULL);
# endif
# if OPENSSL_API_COMPAT < 0x10100000L
SSL_load_error_strings();
# endif
SSL_library_init();
#else
@ -49,32 +49,60 @@ void security_openssl_library()
#endif
}
#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_110
/**
* TLS version
*
* Returns the TLS version depending of the user input.
*
* @param lversion is the user input.
*
* @return it returns the version number.
*/
int tls_select_version(const char *lversion) {
if (!strcmp(lversion, "1") || !strcmp(lversion, "1.0"))
return TLS1_VERSION;
else if (!strcmp(lversion, "1.1"))
return TLS1_1_VERSION;
else if (!strcmp(lversion, "1.2"))
return TLS1_2_VERSION;
#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_111
else if (!strcmp(lversion, "1.3"))
return TLS1_3_VERSION;
#endif
return TLS_MAX_VERSION;
}
#endif
/**
* OpenSSL common options
*
* Clients and SERVER have common options, this function is responsible to set them in the context.
*
* @param ctx
* @param ctx the initialized SSL context.
* @param side 0 means server, and 1 client.
*/
void security_openssl_common_options(SSL_CTX *ctx) {
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
static char *ciphers = {"ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA"};
void security_openssl_common_options(SSL_CTX *ctx, int side) {
#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_110
if (!side) {
int version = tls_select_version(tls_version) ;
#endif
#if OPENSSL_VERSION_NUMBER < 0x10100000L
SSL_CTX_set_options (ctx,SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_COMPRESSION);
#if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_110
SSL_CTX_set_options (ctx,SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_COMPRESSION);
#else
SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
//We are avoiding the TLS v1.3 for while, because Google Chrome
//is giving the message net::ERR_SSL_VERSION_INTERFERENCE with it.
SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION);
#endif
SSL_CTX_set_mode(ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
SSL_CTX_set_max_proto_version(ctx, version);
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
if (!SSL_CTX_set_cipher_list(ctx, ciphers)) {
error("SSL error. cannot set the cipher list");
if(tls_ciphers && strcmp(tls_ciphers, "none") != 0) {
if (!SSL_CTX_set_cipher_list(ctx, tls_ciphers)) {
error("SSL error. cannot set the cipher list");
}
}
}
#endif
SSL_CTX_set_mode(ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
}
/**
@ -86,13 +114,13 @@ void security_openssl_common_options(SSL_CTX *ctx) {
*/
SSL_CTX * security_initialize_openssl_client() {
SSL_CTX *ctx;
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_110
ctx = SSL_CTX_new(SSLv23_client_method());
#else
ctx = SSL_CTX_new(TLS_client_method());
#endif
if(ctx) {
security_openssl_common_options(ctx);
security_openssl_common_options(ctx, 1);
}
return ctx;
@ -111,7 +139,7 @@ static SSL_CTX * security_initialize_openssl_server() {
static int netdata_id_context = 1;
//TO DO: Confirm the necessity to check return for other OPENSSL function
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_110
ctx = SSL_CTX_new(SSLv23_server_method());
if (!ctx) {
error("Cannot create a new SSL context, netdata won't encrypt communication");
@ -128,7 +156,7 @@ static SSL_CTX * security_initialize_openssl_server() {
SSL_CTX_use_certificate_chain_file(ctx, security_cert);
#endif
security_openssl_common_options(ctx);
security_openssl_common_options(ctx, 0);
SSL_CTX_use_PrivateKey_file(ctx,security_key,SSL_FILETYPE_PEM);
@ -142,7 +170,7 @@ static SSL_CTX * security_initialize_openssl_server() {
SSL_CTX_set_session_id_context(ctx,(void*)&netdata_id_context,(unsigned int)sizeof(netdata_id_context));
SSL_CTX_set_info_callback(ctx,security_info_callback);
#if (OPENSSL_VERSION_NUMBER < 0x00905100L)
#if (OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_095)
SSL_CTX_set_verify_depth(ctx,1);
#endif
debug(D_WEB_CLIENT,"SSL GLOBAL CONTEXT STARTED\n");
@ -207,7 +235,7 @@ void security_clean_openssl() {
SSL_CTX_free(netdata_opentsdb_ctx);
}
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_110
ERR_free_strings();
#endif
}

View File

@ -17,9 +17,14 @@
# ifdef ENABLE_HTTPS
#define OPENSSL_VERSION_095 0x00905100L
#define OPENSSL_VERSION_097 0x0907000L
#define OPENSSL_VERSION_110 0x10100000L
#define OPENSSL_VERSION_111 0x10101000L
# include <openssl/ssl.h>
# include <openssl/err.h>
# if (SSLEAY_VERSION_NUMBER >= 0x0907000L) && (OPENSSL_VERSION_NUMBER < 0x10100000L)
# if (SSLEAY_VERSION_NUMBER >= OPENSSL_VERSION_097) && (OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_110)
# include <openssl/conf.h>
# endif
@ -33,6 +38,8 @@ extern SSL_CTX *netdata_client_ctx;
extern SSL_CTX *netdata_srv_ctx;
extern const char *security_key;
extern const char *security_cert;
extern const char *tls_version;
extern const char *tls_ciphers;
extern int netdata_validate_server;
extern int security_location_for_context(SSL_CTX *ctx,char *file,char *path);

View File

@ -109,6 +109,7 @@ int rrdpush_init() {
}
char *invalid_certificate = appconfig_get(&stream_config, CONFIG_SECTION_STREAM, "ssl skip certificate verification", "no");
if ( !strcmp(invalid_certificate,"yes")){
if (netdata_validate_server == NETDATA_SSL_VALID_CERTIFICATE){
info("Netdata is configured to accept invalid SSL certificate.");

View File

@ -67,11 +67,11 @@ The API requests are serviced as follows:
### Enabling TLS support
Since v1.16.0, Netdata supports encrypted HTTP connections to the web server, plus encryption of streaming data between a slave and its master, via the TLS 1.2 protocol.
Since v1.16.0, Netdata supports encrypted HTTP connections to the web server, plus encryption of streaming data between a slave and its master, via the TLS protocol.
Inbound unix socket connections are unaffected, regardless of the TLS settings.\
??? info "Differences in TLS and SSL terminology"
While Netdata uses Transport Layer Security (TLS) 1.2 to encrypt communications rather than the obsolete SSL protocol, it's still common practice to refer to encrypted web connections as `SSL`. Many vendors, like Nginx and even Netdata itself, use `SSL` in configuration files, whereas documentation will always refer to encrypted communications as `TLS` or `TLS/SSL`.
While Netdata uses Transport Layer Security (TLS) to encrypt communications rather than the obsolete SSL protocol, it's still common practice to refer to encrypted web connections as `SSL`. Many vendors, like Nginx and even Netdata itself, use `SSL` in configuration files, whereas documentation will always refer to encrypted communications as `TLS` or `TLS/SSL`.
To enable TLS, provide the path to your certificate and private key in the `[web]` section of `netdata.conf`:
@ -96,6 +96,20 @@ openssl req -newkey rsa:2048 -nodes -sha512 -x509 -days 365 -keyout key.pem -out
openssl speed rsa2048 rsa4096
```
### Select TLS version
Beginning with version 1.21, you can also specify the TLS version and the ciphers that you want to use:
```conf
[web]
tls version = 1.3
tls ciphers = TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256
```
If you do not specify these options, Netdata will use the highest available protocol version on your system and the default cipher list for that protocol provided by your TLS implementation.
While Netdata accepts all the TLS version as arguments (`1` or `1.0`, `1.1`, `1.2` and `1.3`), we recommend you use `1.3` for the most secure encryption.
#### TLS/SSL enforcement
When the certificates are defined and unless any other options are provided, a Netdata server will: