| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | #include "netdata-conf-web.h" |
| 4 | #include "daemon/static_threads.h" |
| 5 | |
| 6 | size_t netdata_conf_web_query_threads(void) { |
| 7 | // See https://github.com/netdata/netdata/issues/11081#issuecomment-831998240 for more details |
| 8 | if (OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_110) { |
| 9 | inicfg_set_number(&netdata_config, CONFIG_SECTION_WEB, "web server threads", 1); |
| 10 | netdata_log_info("You are running an OpenSSL older than 1.1.0, web server will not enable multithreading."); |
| 11 | return 1; |
| 12 | } |
| 13 | |
| 14 | size_t cpus = MIN(netdata_conf_cpus(), 256); // max 256 cores |
| 15 | size_t threads = cpus * (netdata_conf_is_parent() ? 2 : 1); |
| 16 | threads = MAX(threads, 6); |
| 17 | |
| 18 | threads = inicfg_get_number(&netdata_config, CONFIG_SECTION_WEB, "web server threads", threads); |
| 19 | if(threads < 1) { |
| 20 | netdata_log_error("[" CONFIG_SECTION_WEB "].web server threads in netdata.conf needs to be at least 1. Overwriting it."); |
| 21 | threads = 1; |
| 22 | inicfg_set_number(&netdata_config, CONFIG_SECTION_WEB, "web server threads", threads); |
| 23 | } |
| 24 | return threads; |
| 25 | } |
| 26 | |
| 27 | static int make_dns_decision(const char *section_name, const char *config_name, const char *default_value, SIMPLE_PATTERN *p) { |
| 28 | const char *value = inicfg_get(&netdata_config, section_name,config_name,default_value); |
| 29 | |
| 30 | if(!strcmp("yes",value)) |
| 31 | return 1; |
| 32 | |
| 33 | if(!strcmp("no",value)) |
| 34 | return 0; |
| 35 | |
| 36 | if(strcmp("heuristic",value) != 0) |
| 37 | netdata_log_error("Invalid configuration option '%s' for '%s'/'%s'. Valid options are 'yes', 'no' and 'heuristic'. Proceeding with 'heuristic'", |
| 38 | value, section_name, config_name); |
| 39 | |
| 40 | return simple_pattern_is_potential_name(p); |
| 41 | } |
| 42 | |
| 43 | extern struct netdata_static_thread *static_threads; |
| 44 | void web_server_threading_selection(void) { |
| 45 | FUNCTION_RUN_ONCE(); |
| 46 | |
| 47 | web_server_mode = web_server_mode_id(inicfg_get(&netdata_config, CONFIG_SECTION_WEB, "mode", web_server_mode_name(web_server_mode))); |
| 48 | |
| 49 | int static_threaded = (web_server_mode == WEB_SERVER_MODE_STATIC_THREADED); |
| 50 | |
| 51 | int i; |
| 52 | for (i = 0; static_threads[i].name; i++) { |
| 53 | if (static_threads[i].start_routine == socket_listen_main_static_threaded) |
| 54 | static_threads[i].enabled = static_threaded; |
| 55 | } |
| 56 | } |
| 57 | |
| 58 | void netdata_conf_section_web(void) { |
| 59 | FUNCTION_RUN_ONCE(); |
| 60 | |
| 61 | web_client_timeout = |
| 62 | (int)inicfg_get_duration_seconds(&netdata_config, CONFIG_SECTION_WEB, "disconnect idle clients after", web_client_timeout); |
| 63 | |
| 64 | web_client_first_request_timeout = |
| 65 | (int)inicfg_get_duration_seconds(&netdata_config, CONFIG_SECTION_WEB, "timeout for first request", web_client_first_request_timeout); |
| 66 | |
| 67 | web_client_streaming_rate_t = |
| 68 | inicfg_get_duration_seconds(&netdata_config, CONFIG_SECTION_WEB, "accept a streaming request every", web_client_streaming_rate_t); |
| 69 | |
| 70 | respect_web_browser_do_not_track_policy = |
| 71 | inicfg_get_boolean(&netdata_config, CONFIG_SECTION_WEB, "respect do not track policy", respect_web_browser_do_not_track_policy); |
| 72 | web_x_frame_options = inicfg_get(&netdata_config, CONFIG_SECTION_WEB, "x-frame-options response header", ""); |
| 73 | if(!*web_x_frame_options) |
| 74 | web_x_frame_options = NULL; |
| 75 | |
| 76 | web_allow_connections_from = |
| 77 | simple_pattern_create(inicfg_get(&netdata_config, CONFIG_SECTION_WEB, "allow connections from", "localhost *"), |
| 78 | NULL, SIMPLE_PATTERN_EXACT, true); |
| 79 | web_allow_connections_dns = |
| 80 | make_dns_decision(CONFIG_SECTION_WEB, "allow connections by dns", "heuristic", web_allow_connections_from); |
| 81 | web_allow_dashboard_from = |
| 82 | simple_pattern_create(inicfg_get(&netdata_config, CONFIG_SECTION_WEB, "allow dashboard from", "localhost *"), |
| 83 | NULL, SIMPLE_PATTERN_EXACT, true); |
| 84 | web_allow_dashboard_dns = |
| 85 | make_dns_decision(CONFIG_SECTION_WEB, "allow dashboard by dns", "heuristic", web_allow_dashboard_from); |
| 86 | web_allow_badges_from = |
| 87 | simple_pattern_create(inicfg_get(&netdata_config, CONFIG_SECTION_WEB, "allow badges from", "*"), NULL, SIMPLE_PATTERN_EXACT, |
| 88 | true); |
| 89 | web_allow_badges_dns = |
| 90 | make_dns_decision(CONFIG_SECTION_WEB, "allow badges by dns", "heuristic", web_allow_badges_from); |
| 91 | web_allow_registry_from = |
| 92 | simple_pattern_create(inicfg_get(&netdata_config, CONFIG_SECTION_REGISTRY, "allow from", "*"), NULL, SIMPLE_PATTERN_EXACT, |
| 93 | true); |
| 94 | web_allow_registry_dns = make_dns_decision(CONFIG_SECTION_REGISTRY, "allow by dns", "heuristic", |
| 95 | web_allow_registry_from); |
| 96 | web_allow_streaming_from = simple_pattern_create(inicfg_get(&netdata_config, CONFIG_SECTION_WEB, "allow streaming from", "*"), |
| 97 | NULL, SIMPLE_PATTERN_EXACT, true); |
| 98 | web_allow_streaming_dns = make_dns_decision(CONFIG_SECTION_WEB, "allow streaming by dns", "heuristic", |
| 99 | web_allow_streaming_from); |
| 100 | // Note the default is not heuristic, the wildcards could match DNS but the intent is ip-addresses. |
| 101 | web_allow_netdataconf_from = simple_pattern_create(inicfg_get(&netdata_config, CONFIG_SECTION_WEB, "allow netdata.conf from", |
| 102 | "localhost fd* 10.* 192.168.* 172.16.* 172.17.* 172.18.*" |
| 103 | " 172.19.* 172.20.* 172.21.* 172.22.* 172.23.* 172.24.*" |
| 104 | " 172.25.* 172.26.* 172.27.* 172.28.* 172.29.* 172.30.*" |
| 105 | " 172.31.* UNKNOWN"), NULL, SIMPLE_PATTERN_EXACT, |
| 106 | true); |
| 107 | web_allow_netdataconf_dns = |
| 108 | make_dns_decision(CONFIG_SECTION_WEB, "allow netdata.conf by dns", "no", web_allow_netdataconf_from); |
| 109 | web_allow_mgmt_from = |
| 110 | simple_pattern_create(inicfg_get(&netdata_config, CONFIG_SECTION_WEB, "allow management from", "localhost"), |
| 111 | NULL, SIMPLE_PATTERN_EXACT, true); |
| 112 | web_allow_mgmt_dns = |
| 113 | make_dns_decision(CONFIG_SECTION_WEB, "allow management by dns","heuristic",web_allow_mgmt_from); |
| 114 | |
| 115 | web_enable_gzip = inicfg_get_boolean(&netdata_config, CONFIG_SECTION_WEB, "enable gzip compression", web_enable_gzip); |
| 116 | |
| 117 | const char *s = inicfg_get(&netdata_config, CONFIG_SECTION_WEB, "gzip compression strategy", "default"); |
| 118 | if(!strcmp(s, "default")) |
| 119 | web_gzip_strategy = Z_DEFAULT_STRATEGY; |
| 120 | else if(!strcmp(s, "filtered")) |
| 121 | web_gzip_strategy = Z_FILTERED; |
| 122 | else if(!strcmp(s, "huffman only")) |
| 123 | web_gzip_strategy = Z_HUFFMAN_ONLY; |
| 124 | else if(!strcmp(s, "rle")) |
| 125 | web_gzip_strategy = Z_RLE; |
| 126 | else if(!strcmp(s, "fixed")) |
| 127 | web_gzip_strategy = Z_FIXED; |
| 128 | else { |
| 129 | netdata_log_error("Invalid compression strategy '%s'. Valid strategies are 'default', 'filtered', 'huffman only', 'rle' and 'fixed'. Proceeding with 'default'.", s); |
| 130 | web_gzip_strategy = Z_DEFAULT_STRATEGY; |
| 131 | } |
| 132 | |
| 133 | web_gzip_level = (int)inicfg_get_number(&netdata_config, CONFIG_SECTION_WEB, "gzip compression level", 3); |
| 134 | if(web_gzip_level < 1) { |
| 135 | netdata_log_error("Invalid compression level %d. Valid levels are 1 (fastest) to 9 (best ratio). Proceeding with level 1 (fastest compression).", web_gzip_level); |
| 136 | web_gzip_level = 1; |
| 137 | } |
| 138 | else if(web_gzip_level > 9) { |
| 139 | netdata_log_error("Invalid compression level %d. Valid levels are 1 (fastest) to 9 (best ratio). Proceeding with level 9 (best compression).", web_gzip_level); |
| 140 | web_gzip_level = 9; |
| 141 | } |
| 142 | } |
| 143 | |
| 144 | void netdata_conf_web_security_init(void) { |
| 145 | FUNCTION_RUN_ONCE(); |
| 146 | |
| 147 | char filename[FILENAME_MAX + 1]; |
| 148 | snprintfz(filename, FILENAME_MAX, "%s/ssl/key.pem", netdata_configured_user_config_dir); |
| 149 | netdata_ssl_security_key = inicfg_get_filename(&netdata_config, CONFIG_SECTION_WEB, "ssl key", filename); |
| 150 | |
| 151 | snprintfz(filename, FILENAME_MAX, "%s/ssl/cert.pem", netdata_configured_user_config_dir); |
| 152 | netdata_ssl_security_cert = inicfg_get_filename(&netdata_config, CONFIG_SECTION_WEB, "ssl certificate", filename); |
| 153 | |
| 154 | tls_version = inicfg_get(&netdata_config, CONFIG_SECTION_WEB, "tls version", "1.3"); |
| 155 | tls_ciphers = inicfg_get(&netdata_config, CONFIG_SECTION_WEB, "tls ciphers", "none"); |
| 156 | } |