Commit 164e78cd authored by Stefan Eissing's avatar Stefan Eissing
Browse files

On the trunk:

mod_md: v0.9.6: a "MDRequireHttps permament" configured domain automatically sends out HSTS (rfc 6797) headers in https: responses. 



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1808444 13f79535-47bb-0310-9956-ffa450edef68
parent 0b9673c9
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
                                                         -*- coding: utf-8 -*-
Changes with Apache 2.5.0

  *) mod_md: v0.9.6: a "MDRequireHttps permament" configured domain automatically sends out
     HSTS (rfc 6797) headers in https: responses. [Stefan Eissing]

  *) mod_ssl: adding ssl_policies.h[.in] for policy cipher/protocol definitions. Use 
     update_policies.py to update manually from Mozilla JSON definitions at
     https://statics.tls.security.mozilla.org/server-side-tls-conf.json
+11 −0
Original line number Diff line number Diff line
@@ -501,6 +501,17 @@ MDRequireHttps permanent
</ManagedDomain>
                </highlight>
            </example>
            <p>When you configure MDRequireHttps permanent, an additional security 
            feature is automatically applied: HSTS. This adds the header 
            Strict-Transport-Security to responses sent out via https:. 
            Basically, this instructs the browser to only perform secure 
            communications with that domain. This instruction holds for the 
            amount of time specified in the header as 'max-age'. 
            This is about half a year as generated by mod_md.
            </p><p>
            It is therefore advisable to first test the MDRequireHttps temporary 
            configuration and switch to permanent only once that works satisfactory.
            </p>
        </usage>
    </directivesynopsis>

+4 −0
Original line number Diff line number Diff line
@@ -32,6 +32,10 @@ struct md_pkey_spec_t;
#define MD_PKEY_RSA_BITS_MIN       2048
#define MD_PKEY_RSA_BITS_DEF       2048

/* Minimum age for the HSTS header (RFC 6797), considered appropriate by Mozilla Security */
#define MD_HSTS_HEADER             "Strict-Transport-Security"
#define MD_HSTS_MAX_AGE_DEFAULT    15768000

typedef enum {
    MD_S_UNKNOWN,                   /* MD has not been analysed yet */
    MD_S_INCOMPLETE,                /* MD is missing necessary information, cannot go live */
+2 −2
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@
 * @macro
 * Version number of the md module as c string
 */
#define MOD_MD_VERSION "0.9.5"
#define MOD_MD_VERSION "0.9.6"

/**
 * @macro
@@ -34,7 +34,7 @@
 * release. This is a 24 bit number with 8 bits for major number, 8 bits
 * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
 */
#define MOD_MD_VERSION_NUM 0x000905
#define MOD_MD_VERSION_NUM 0x000906

#define MD_EXPERIMENTAL 0
#define MD_ACME_DEF_URL    "https://acme-v01.api.letsencrypt.org/directory"
+42 −31
Original line number Diff line number Diff line
@@ -253,7 +253,7 @@ static apr_status_t assign_to_servers(md_t *md, server_rec *base_server,
                /* We require https for this MD, but do we have port 443 (or a mapped one)
                 * available? */
                if (mc->local_443 <= 0) {
                    ap_log_error(APLOG_MARK, APLOG_ERR, 0, base_server, APLOGNO(10089)
                    ap_log_error(APLOG_MARK, APLOG_ERR, 0, base_server, APLOGNO()
                                 "MDPortMap says there is no port for https (443), "
                                 "but MD %s is configured to require https. This "
                                 "only works when a 443 port is available.", md->name);
@@ -275,7 +275,7 @@ static apr_status_t assign_to_servers(md_t *md, server_rec *base_server,
                if (!s_https) {
                    /* Did not find any server_rec that matches this MD *and* has an
                     * s->addrs match for the https port. Suspicious. */
                    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server, APLOGNO(10090)
                    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server, APLOGNO()
                                 "MD %s is configured to require https, but there seems to be "
                                 "no VirtualHost for it that has port %d in its address list. "
                                 "This looks as if it will not work.", 
@@ -697,7 +697,7 @@ static apr_status_t run_watchdog(int state, void *baton, apr_pool_t *ptemp)

            now = apr_time_now();
            if (APLOGdebug(wd->s)) {
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, wd->s, APLOGNO(10091)
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, wd->s, APLOGNO()
                             "next run in %s", md_print_duration(ptemp, next_run - now));
            }
            wd_set_interval(wd->watchdog, next_run - now, wd, run_watchdog);
@@ -881,6 +881,7 @@ static apr_status_t md_post_config(apr_pool_t *p, apr_pool_t *plog,
    apr_status_t rv = APR_SUCCESS;
    int i;

    md_config_post_config(s, p);
    sc = md_config_get(s);
    mc = sc->mc;
    
@@ -1005,14 +1006,14 @@ static apr_status_t md_get_certificate(server_rec *s, apr_pool_t *p,
        assert(sc->mc);
        assert(sc->mc->store);
        if (APR_SUCCESS != (rv = md_reg_init(&reg, p, sc->mc->store, sc->mc->proxy_url))) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10092) "init registry");
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO() "init registry");
            return rv;
        }

        md = md_reg_get(reg, sc->assigned->name, p);
            
        if (APR_SUCCESS != (rv = md_reg_get_cred_files(reg, md, p, pkeyfile, pcertfile))) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10093) 
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO() 
                         "retrieving credentials for MD %s", md->name);
            return rv;
        }
@@ -1169,12 +1170,21 @@ static int md_require_https_maybe(request_rec *r)
    const char *s;
    int status;
    
    if (strncmp(WELL_KNOWN_PREFIX, r->parsed_uri.path, sizeof(WELL_KNOWN_PREFIX)-1)) {
    if (opt_ssl_is_https 
        && strncmp(WELL_KNOWN_PREFIX, r->parsed_uri.path, sizeof(WELL_KNOWN_PREFIX)-1)) {
        
        sc = ap_get_module_config(r->server->module_config, &md_module);
        if (sc && sc->assigned && sc->assigned->require_https > MD_REQUIRE_OFF 
            && opt_ssl_is_https && !opt_ssl_is_https(r->connection)) {
            /* Do not have https:, but require it. Redirect the request accordingly. 
             */
        if (sc && sc->assigned && sc->assigned->require_https > MD_REQUIRE_OFF) {
            if (opt_ssl_is_https(r->connection)) {
                /* Using https:
                 * if 'permanent' and no one else set a HSTS header already, do it */
                if (sc->assigned->require_https == MD_REQUIRE_PERMANENT 
                    && sc->mc->hsts_header && !apr_table_get(r->headers_out, MD_HSTS_HEADER)) {
                    apr_table_setn(r->headers_out, MD_HSTS_HEADER, sc->mc->hsts_header);
                }
            }
            else {
                /* Not using https:, but require it. Redirect. */
                if (r->method_number == M_GET) {
                    /* safe to use the old-fashioned codes */
                    status = ((MD_REQUIRE_PERMANENT == sc->assigned->require_https)? 
@@ -1201,6 +1211,7 @@ static int md_require_https_maybe(request_rec *r)
                }
            }
        }
    }
    return DECLINED;
}

@@ -1233,7 +1244,7 @@ static void md_hooks(apr_pool_t *pool)
    /* answer challenges *very* early, before any configured authentication may strike */
    ap_hook_post_read_request(md_http_challenge_pr, NULL, NULL, APR_HOOK_MIDDLE);
    /* redirect to https if configured */
    ap_hook_fixups(md_require_https_maybe, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_fixups(md_require_https_maybe, NULL, NULL, APR_HOOK_LAST);

    APR_REGISTER_OPTIONAL_FN(md_is_managed);
    APR_REGISTER_OPTIONAL_FN(md_get_certificate);
Loading