From 8b47863cd45cf4685b74f5390a800c1e28b721b9 Mon Sep 17 00:00:00 2001 From: Joris Vink Date: Tue, 15 Oct 2013 10:44:56 +0200 Subject: [PATCH] Add http_hsts_enable (enabled by default with max-age=31536000) to Kore's configuration file. If enabled Kore adds the HSTS header to every response. - Additionally, fix some typos in the example configuration. - Change default SSL cipher list again, no more RC4 and almost PFS for all browsers. --- includes/http.h | 2 ++ includes/kore.h | 2 +- modules/example/module.conf | 14 ++++++++++---- src/config.c | 24 ++++++++++++++++++++++++ src/http.c | 15 +++++++++++++++ 5 files changed, 52 insertions(+), 5 deletions(-) diff --git a/includes/http.h b/includes/http.h index bf26973..ef36c03 100644 --- a/includes/http.h +++ b/includes/http.h @@ -17,6 +17,7 @@ #ifndef __H_HTTP_H #define __H_HTTP_H +#define HTTP_HSTS_ENABLE 31536000 #define HTTP_HEADER_MAX_LEN 4096 #define HTTP_POSTBODY_MAX_LEN 10240000 #define HTTP_URI_LEN 2000 @@ -80,6 +81,7 @@ struct http_request { extern int http_request_count; extern u_int16_t http_header_max; extern u_int64_t http_postbody_max; +extern u_int64_t http_hsts_enable; void http_init(void); void http_process(void); diff --git a/includes/kore.h b/includes/kore.h index 3c09519..4ea0550 100644 --- a/includes/kore.h +++ b/includes/kore.h @@ -46,7 +46,7 @@ #define KORE_DOMAINNAME_LEN 254 #define KORE_PIDFILE_DEFAULT "/var/run/kore.pid" -#define KORE_DEFAULT_CIPHER_LIST "EECDH+AES:EDH+AES:-SHA1:EECDH+RC4:EDH+RC4:RC4-SHA:EECDH+AES256:EDH+AES256:AES256-SHA:!aNULL:!eNULL:!EXP:!LOW:!MD5" +#define KORE_DEFAULT_CIPHER_LIST "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384: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-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK" #if defined(KORE_DEBUG) #define kore_debug(fmt, ...) \ diff --git a/modules/example/module.conf b/modules/example/module.conf index 0cf6a49..3913fbf 100644 --- a/modules/example/module.conf +++ b/modules/example/module.conf @@ -4,7 +4,7 @@ bind 127.0.0.1 443 bind ::1 443 -# The path worker processes will chroot too after starting. +# The path worker processes will chroot into after starting. chroot /home/joris/src/kore # Worker processes will run as the specified user. @@ -25,7 +25,7 @@ workers 4 #onload myinit # You can define a callback Kore calls from its parent process or -# workers everytime # the kore_cb_interval timer (in milliseconds) is reached. +# workers everytime the kore_cb_interval timer (in milliseconds) is reached. # # NOTE: Remember that the parent process runs as root and is not chroot(). # NOTE: If you want the cb to run on a worker, be sure to set kore_cb_worker. @@ -36,21 +36,25 @@ workers 4 # HTTP specific settings. # http_header_max Maximum size of HTTP headers (in bytes). # http_postbody_max Maximum size of an HTTP POST body (in bytes). +# http_hsts_enable Send Strict Transport Security header in +# all responses. Parameter is the age. +# Set age to 0 to disable sending this header. #http_header_max 4096 #http_postbody_max 10240000 +#http_hsts_enable 31536000 # Specifies what module to be loaded. load modules/example/example.module # Specify the SSL ciphers that will be used. -#ssl_cipher EECDH+AES:EDH+AES:-SHA1:EECDH+RC4:EDH+RC4:RC4-SHA:EECDH+AES256:EDH+AES256:AES256-SHA:!aNULL:!eNULL:!EXP:!LOW:!MD5 +#ssl_cipher ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384: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-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK # If you wish to use EDH / ECDH specify a file containing # a generated DH key (See OpenSSL dhparam). #ssl_dhparam dh2048.pem # Set this if you want to disable SSL zlib compression. -#ssl_no_compression +ssl_no_compression # Specify the amount of seconds a SPDY connection is kept open. # You can keep it open indefinately by setting this to 0. @@ -78,6 +82,8 @@ domain localhost { certfile cert/server.crt certkey cert/server.key accesslog /var/log/kore_access.log + + # Page handlers static /css/style.css serve_style_css static / serve_index static /intro.jpg serve_intro diff --git a/src/config.c b/src/config.c index ca3df4d..72d9290 100644 --- a/src/config.c +++ b/src/config.c @@ -44,6 +44,7 @@ static int configure_kore_cb_interval(char **); static int configure_kore_cb_worker(char **); static int configure_http_header_max(char **); static int configure_http_postbody_max(char **); +static int configure_http_hsts_enable(char **); static void domain_sslstart(void); static struct { @@ -73,6 +74,7 @@ static struct { { "kore_cb_interval", configure_kore_cb_interval }, { "http_header_max", configure_http_header_max }, { "http_postbody_max", configure_http_postbody_max }, + { "http_hsts_enable", configure_http_hsts_enable }, { NULL, NULL }, }; @@ -551,6 +553,28 @@ configure_http_postbody_max(char **argv) return (KORE_RESULT_OK); } +static int +configure_http_hsts_enable(char **argv) +{ + int err; + + if (argv[1] == NULL) + return (KORE_RESULT_ERROR); + + if (http_hsts_enable != HTTP_HSTS_ENABLE) { + kore_debug("http_hsts_enable already set"); + return (KORE_RESULT_ERROR); + } + + http_hsts_enable = kore_strtonum(argv[1], 10, 1, ULONG_MAX, &err); + if (err != KORE_RESULT_OK) { + printf("bad http_hsts_enable value: %s\n", argv[1]); + return (KORE_RESULT_ERROR); + } + + return (KORE_RESULT_OK); +} + static void domain_sslstart(void) { diff --git a/src/http.c b/src/http.c index 335ce8c..9d679bf 100644 --- a/src/http.c +++ b/src/http.c @@ -31,6 +31,7 @@ static struct kore_pool http_request_pool; static struct kore_pool http_header_pool; int http_request_count; +u_int64_t http_hsts_enable = HTTP_HSTS_ENABLE; u_int16_t http_header_max = HTTP_HEADER_MAX_LEN; u_int64_t http_postbody_max = HTTP_POSTBODY_MAX_LEN; @@ -258,6 +259,14 @@ http_response(struct http_request *req, int status, u_int8_t *d, u_int32_t len) spdy_header_block_add(hblock, ":status", sbuf); spdy_header_block_add(hblock, ":version", "HTTP/1.1"); spdy_header_block_add(hblock, ":server", KORE_NAME_STRING); + + if (http_hsts_enable) { + snprintf(sbuf, sizeof(sbuf), + "max-age=%lu", http_hsts_enable); + spdy_header_block_add(hblock, + ":strict-transport-security", sbuf); + } + TAILQ_FOREACH(hdr, &(req->resp_headers), list) spdy_header_block_add(hblock, hdr->header, hdr->value); @@ -293,6 +302,12 @@ http_response(struct http_request *req, int status, u_int8_t *d, u_int32_t len) kore_buf_appendf(buf, "Keep-Alive: timeout=20\r\n"); kore_buf_appendf(buf, "Server: %s\r\n", KORE_NAME_STRING); + if (http_hsts_enable) { + kore_buf_appendf(buf, + "Strict-Transport-Security: max-age=%lu\r\n", + http_hsts_enable); + } + TAILQ_FOREACH(hdr, &(req->resp_headers), list) { kore_buf_appendf(buf, "%s: %s\r\n", hdr->header, hdr->value);