it-swarm.com.de

Aktivieren Sie http2 mit Tomcat in Spring Boot

Tomcat 8.5, Das die Standardeinstellung in Spring Boot 1.4 Ist (wird morgen veröffentlicht), unterstützt http2.

Wie kann http2 In einer Spring Boot - Anwendung aktiviert werden?

34
yglodt

Die eleganteste und leistungsstärkste Möglichkeit, HTTP/2 mit einer Spring Boot-Anwendung folgt hier.

Zunächst müssen Sie, wie in Andy Wilkinsons Antwort erwähnt, HTTP/2 auf Tomcat-Ebene aktivieren:

@Bean
public EmbeddedServletContainerCustomizer tomcatCustomizer() {
    return (container) -> {
        if (container instanceof TomcatEmbeddedServletContainerFactory) {
            ((TomcatEmbeddedServletContainerFactory) container)
                    .addConnectorCustomizers((connector) -> {
                connector.addUpgradeProtocol(new Http2Protocol());
            });
        }
    };
}

Wenn Sie keinen eingebetteten Tomcat verwenden, können Sie das HTTP/2-Listening folgendermaßen einrichten:

<Connector port="5080" protocol="HTTP/1.1" connectionTimeout="20000">
    <UpgradeProtocol className="org.Apache.coyote.http2.Http2Protocol" />
</Connector>

Denken Sie daran, dass Sie Tomcat> = 8.5 benötigen.

Verwenden Sie dann HAProxy (Version> = 1.7) vor Tomcat, um die Verschlüsselung sicherzustellen.

Der Client spricht https mit HAProxy und HAProxy spricht nach Aufforderung des Clients Klartext-HTTP/1.1 oder HTTP/2 mit dem Backend. Es gibt keine unnötigen Protokollübersetzungen.

Die passende HAProxy-Konfiguration finden Sie hier:

# Create PEM: cat cert.crt cert.key ca.crt > /etc/ssl/certs/cert.pem

global
    tune.ssl.default-dh-param 2048
    ssl-default-bind-options no-sslv3 no-tls-tickets force-tlsv12
    ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
    chroot /var/lib/haproxy
    user haproxy
    group haproxy

defaults
    timeout connect 10000ms
    timeout client 60000ms
    timeout server 60000ms

frontend fe_https
    mode tcp
    rspadd Strict-Transport-Security:\ max-age=31536000;\ includeSubDomains;\ preload
    rspadd X-Frame-Options:\ DENY
    bind *:443 ssl crt /etc/ssl/certs/cert.pem alpn h2,http/1.1
    default_backend be_http

backend be_http
    mode tcp
    server domain 127.0.0.1:8080
    # compression algo gzip # does not work in mode "tcp"
    # compression type text/html text/css text/javascript application/json

Edit 2019

Ich habe zwei Probleme, wenn ich den Modus "tcp" benutze

  • Die Komprimierung funktioniert nicht, da dies vom http-Modus abhängt. Das Backend muss sich also darum kümmern
  • Das Backend kann die IP-Adresse des Clients nicht sehen. Wahrscheinlich brauche ich NAT. Untersuchung läuft noch ...

Da Haproxy-Proxys eine TCP-Verbindung auf niedrigerer Ebene verwenden, gibt es im Allgemeinen keinen Zugriff auf http-Inhalte

17
yglodt

Sie müssen das HTTP 2-Aktualisierungsprotokoll zum Tomcat-Connector hinzufügen. Sie können dies tun, indem Sie den eingebetteten Tomcat-Container anpassen:

Java 8:

@Bean
public EmbeddedServletContainerCustomizer tomcatCustomizer() {
    return (container) -> {
        if (container instanceof TomcatEmbeddedServletContainerFactory) {
            ((TomcatEmbeddedServletContainerFactory) container)
                    .addConnectorCustomizers((connector) -> {
                connector.addUpgradeProtocol(new Http2Protocol());
            });
        }
    };
}

Java 7:

@Bean
public EmbeddedServletContainerCustomizer tomcatCustomizer() {
    return new EmbeddedServletContainerCustomizer() {

        @Override
        public void customize(ConfigurableEmbeddedServletContainer container) {
            if (container instanceof TomcatEmbeddedServletContainerFactory) {
                ((TomcatEmbeddedServletContainerFactory) container)
                        .addConnectorCustomizers(new TomcatConnectorCustomizer() {
                    @Override
                    public void customize(Connector connector) {
                        connector.addUpgradeProtocol(new Http2Protocol());
                    }

                });
            }
        }

    };
}
29
Andy Wilkinson

In Spring Boot 2.1 und höher ist es so einfach, diese Eigenschaft zu Ihrer .properties-Datei (oder .yml-Datei) hinzuzufügen:

server.http2.enabled=true

Sie können dies auch programmgesteuert durchführen (in einer Ihrer Konfigurationsklassen):

@Bean
public ConfigurableServletWebServerFactory tomcatCustomizer() {
    TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
    factory.addConnectorCustomizers(connector -> connector.addUpgradeProtocol(new Http2Protocol()));
    return factory;
}
17
Mahozad

In Spring Boot 2 benötigen Sie zunächst ein Zertifikat, das folgendermaßen generiert werden kann:

keytool -genkey -keyalg RSA -alias my-the-best-api -keystore c:\tmp\keystore.store -storepass secret -validity 3650 -keysize 2048

Dann müssen Sie nur dieses Zertifikat zum Klassenpfad hinzufügen und die erforderlichen Eigenschaften zu application.properties hinzufügen:

server.http2.enabled=true
server.port = 8443
server.ssl.key-store=classpath:keystore.jks
server.ssl.key-password=secret
9
Jozef Najman