4

I'm running Apache 2.4.20 on Ubuntu and I have SSL configured. I have a SAN SSL Certificate and www.example.com and www2.example.com are sharing the same certificate.

I'm getting a 421 Misdirected Request error when I include the following:

Protocols h2 h2c http/1.1
H2Upgrade on
H2Direct
H2WindowSize 128000

Websites run normally if I remove them.

I'm getting the error if ON THE SAME BROWSER, www.example.com and www2.example.com are opened. If I go to www.example.com first then it will load properly. I get the error when I load a second site from that SAN SSL Certificate, like www2.example.com. It does not matter what site I go to first. It always responds with the 421 Misdirected Request on the second site.

What is wrong with my use of the HTTP/2 directives? (They are in the VirtualHost by the way)

Or is there an issue with HTTP/2 and SAN SSL implementations?

And if it matters, both www.example.com and www2.example.com are on the same server hosted in AWS.

Thanks.

EDIT:

I also tried the settings below with the same results.

Protocols h2 http/1.1
H2Direct
H2WindowSize 128000

In the SSL Config

<IfModule mod_ssl.c>

    SSLRandomSeed startup builtin
    SSLRandomSeed startup file:/dev/urandom 512
    SSLRandomSeed connect builtin
    SSLRandomSeed connect file:/dev/urandom 512

    AddType application/x-x509-ca-cert .crt
    AddType application/x-pkcs7-crl .crl

    SSLPassPhraseDialog  exec:/usr/share/apache2/ask-for-passphrase

    SSLSessionCache     shmcb:${APACHE_RUN_DIR}/ssl_scache(512000)
    SSLSessionCacheTimeout  300

    SSLOpenSSLConfCmd DHParameters "/path/dhparams.pem"

    SSLCipherSuite ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS

    SSLHonorCipherOrder on

    SSLCompression Off
    SSLSessionTickets Off

    SSLUseStapling On
    SSLStaplingResponderTimeout 5
    SSLStaplingReturnResponderErrors off
    SSLStaplingCache shmcb:${APACHE_RUN_DIR}/ssl_stapling(32768)

    SSLProtocol all -SSLv3

    SSLInsecureRenegotiation Off
    SSLStrictSNIVHostCheck Off

</IfModule>

In the VirtualHost

<IfModule mod_ssl.c>
  <VirtualHost *:443>
    ServerAdmin mail@example.com
    ServerName www.example.com
    DocumentRoot /path/path

    Protocols h2 http/1.1
    H2Direct on
    H2WindowSize 128000

    SSLEngine on
    SSLCACertificateFile /path/cert.crt
    SSLCertificateFile /path/cert.crt
    SSLCertificateKeyFile /path/key.key

    SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
    Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains; preload"

    <Directory /path/path>
        AllowOverride None
        Require all granted
    </Directory>

 </VirtualHost>
</IfModule>
jarvis
  • 2,006
  • 4
  • 18
  • 31
  • Can you show us the SSL configuration part here?. You can also refer to this Doc. for SSL setup with HTTP/2 -> https://http2.github.io/http2-spec/#MisdirectedRequest – serverliving.com Apr 26 '16 at 06:22
  • @serverliving.com Edited the post and included the SSL config and the VirtualHost config. – jarvis Apr 26 '16 at 06:40
  • 1
    Please try without H2Direct and H2WindowSize. –  Apr 26 '16 at 06:49
  • Also try adding www2.example.com as a ServerAlias – serverliving.com Apr 26 '16 at 06:58
  • @serverliving.com I can't add www2 as a ServerAlias since they have different DocumentRoots. Serving different sites here. – jarvis Apr 26 '16 at 07:29
  • 1
    Alright, You have to just make sure that your SSL configurations are same for both the virtual hosts using same SSL certificates. as per this Doc. https://httpd.apache.org/docs/2.4/mod/mod_http2.html#h2direct – serverliving.com Apr 26 '16 at 07:32
  • 1
    @Jason Problem solved with your suggestion. I only now have **Protocols h2 http/1.1**. Good to know what's with the other directives that caused the issue. – jarvis Apr 26 '16 at 16:14
  • @serverliving.com You gave me the link I needed but I didn't immediately see it... I had to dig for it. But you were right. I had different SSL configurations thus it resulted to 421. Thank you. – jarvis Apr 27 '16 at 13:42
  • @jarvis, Glad that it worked for you. :) – serverliving.com Apr 28 '16 at 06:02

2 Answers2

6

This was a real issue for me. But I found the answer here.

Multiple Hosts and Misdirected Requests

Many sites use the same TLS certificate for multiple virtual hosts. The certificate either has a wildcard name, such as '*.example.org' or carries several alternate names. Browsers using HTTP/2 will recognize that and reuse an already opened connection for such hosts.

While this is great for performance, it comes at a price: such vhosts need more care in their configuration. The problem is that you will have multiple requests for multiple hosts on the same TLS connection. And that makes renegotiation impossible, in face the HTTP/2 standard forbids it.

So, if you have several virtual hosts using the same certificate and want to use HTTP/2 for them, you need to make sure that all vhosts have exactly the same SSL configuration. You need the same protocol, ciphers and settings for client verification.

If you mix things, Apache httpd will detect it and return a special response code, 421 Misdirected Request, to the client.

I have 3 VirtualHosts sharing the same certificate. Both of them are configured using my "default" SSL setup. The last one had special configuration since I did not need the last one to be compatible with a lot of browsers so I used more modern ciphers and only the latest SSL Protocol. That particular "special" VirtualHost was getting the 421.

If I disable Protocol h2 http/1.1 that would fix the problem but I did not want to disable that.

After using the same configuration on all VirtualHost sharing the same certificate, the problem was fixed.

jarvis
  • 2,006
  • 4
  • 18
  • 31
  • The statement regarding having the same `SSLProtocol` for all virtual hosts resolved the issue for me. I have confirmed using the `abs.exe` tool that I can replicate the issue and after making sure the `SSLProtocol` matched confirmed with the `abs.exe` tool that the issue is resolved. – radimpe Feb 08 '18 at 14:15
3

I encountered this problem today and was a bit puzzled at first, because I didnt use any different ciphers etc. so I could not understand what the "if you mix things" note from the answer above was really all about. Well, it turned out, that it isnt sufficient if SSLCertificateFile and SSLCertificateKeyFile has the same content and if the files are even identical copies from each other. Those configuration settings have to point to the very same file! I suspect this is, because it isnt the browser who actually sees a problem (as I initially thought to be the case) but rather Apache is already detecting that the configuration isnt the same and blocks any HTTP2 requests pre-emptively because it expects the browser's gonna have a problem if it really delivered the page (which probably might very well happen indeed). Apache is also writing a corresponding error to its log file ("Hostname www.example.com provided via SNI and hostname www2.example.com provided via HTTP have no compatible SSL setup"). This setup compatibility test seems to be rather simple and doesnt care about the fact that the certificate is in fact the same. It probably only notices the different filenames/paths and then balks.

Ranjan
  • 31
  • 1