diff --git a/README.lwsws.md b/README.lwsws.md index a301e9f2..1a0492d2 100644 --- a/README.lwsws.md +++ b/README.lwsws.md @@ -165,6 +165,8 @@ Other vhost options - "`unix-socket`": "1" causes the unix socket specified in the interface option to be used instead of an INET socket + - "`sts`": "1" causes lwsws to send a Strict Transport Security header with responses that informs the client he should never accept to connect to this address using http. This is needed to get the A+ security rating from SSL Labs for your server. + Mounts ------ diff --git a/lib/context.c b/lib/context.c index be3c5eec..d7dbe1f0 100644 --- a/lib/context.c +++ b/lib/context.c @@ -227,7 +227,7 @@ lws_create_vhost(struct lws_context *context, vh->count_protocols++) ; - vh->options = context->options; + vh->options = info->options; vh->pvo = info->pvo; vh->keepalive_timeout = info->keepalive_timeout; @@ -350,6 +350,9 @@ lws_create_vhost(struct lws_context *context, vh->ka_interval = info->ka_interval; vh->ka_probes = info->ka_probes; + if (vh->options & LWS_SERVER_OPTION_STS) + lwsl_notice(" STS enabled\n"); + if (lws_context_init_server_ssl(info, vh)) goto bail; diff --git a/lib/header.c b/lib/header.c index 55265fc4..13f64608 100644 --- a/lib/header.c +++ b/lib/header.c @@ -206,6 +206,13 @@ lws_return_http_status(struct lws *wsi, unsigned int code, &p, end)) return 1; + if (wsi->vhost->options & LWS_SERVER_OPTION_STS) + if (lws_add_http_header_by_name(wsi, (unsigned char *) + "Strict-Transport-Security:", + (unsigned char *)"max-age=15768000 ; " + "includeSubDomains", 36, &p, end)) + return 1; + if (lws_finalize_http_header(wsi, &p, end)) return 1; diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index 9f584076..4f3e3032 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -333,6 +333,7 @@ enum lws_context_options { LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT = (1 << 12), LWS_SERVER_OPTION_EXPLICIT_VHOSTS = (1 << 13), LWS_SERVER_OPTION_UNIX_SOCK = (1 << 14), + LWS_SERVER_OPTION_STS = (1 << 15), /****** add new things just above ---^ ******/ }; diff --git a/lwsws/conf.c b/lwsws/conf.c index 9c2bb068..d032df87 100644 --- a/lwsws/conf.c +++ b/lwsws/conf.c @@ -42,6 +42,7 @@ static const char * const paths_vhosts[] = { "vhosts[].port", "vhosts[].interface", "vhosts[].unix-socket", + "vhosts[].sts", "vhosts[].host-ssl-key", "vhosts[].host-ssl-cert", "vhosts[].host-ssl-ca", @@ -63,6 +64,7 @@ enum lejp_vhost_paths { LEJPVP_PORT, LEJPVP_INTERFACE, LEJPVP_UNIXSKT, + LEJPVP_STS, LEJPVP_HOST_SSL_KEY, LEJPVP_HOST_SSL_CERT, LEJPVP_HOST_SSL_CA, @@ -190,7 +192,8 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason) "!AES256-SHA256"; a->info->pvo = NULL; a->info->keepalive_timeout = 60; - a->info->options &= ~(LWS_SERVER_OPTION_UNIX_SOCK); + a->info->options &= ~(LWS_SERVER_OPTION_UNIX_SOCK | + LWS_SERVER_OPTION_STS); } if (reason == LEJPCB_OBJECT_START && @@ -280,6 +283,12 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason) else a->info->options &= ~(LWS_SERVER_OPTION_UNIX_SOCK); return 0; + case LEJPVP_STS: + if (arg_to_bool(ctx->buf)) + a->info->options |= LWS_SERVER_OPTION_STS; + else + a->info->options &= ~(LWS_SERVER_OPTION_STS); + return 0; case LEJPVP_HOST_SSL_KEY: a->info->ssl_private_key_filepath = a->p; break;