SSL-Handshake-Warnung: Fehler "Nicht erkannter Name" seit dem Upgrade auf Java 1.7.0

225

Ich habe heute ein Upgrade von Java 1.6 auf Java 1.7 durchgeführt. Seitdem tritt ein Fehler auf, wenn ich versuche, über SSL eine Verbindung zu meinem Webserver herzustellen:

javax.net.ssl.SSLProtocolException: handshake alert:  unrecognized_name
    at sun.security.ssl.ClientHandshaker.handshakeAlert(ClientHandshaker.java:1288)
    at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1904)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1027)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1262)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1289)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1273)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:523)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1296)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
    at java.net.URL.openStream(URL.java:1035)

Hier ist der Code:

SAXBuilder builder = new SAXBuilder();
Document document = null;

try {
    url = new URL(https://some url);
    document = (Document) builder.build(url.openStream());
} catch (NoSuchAlgorithmException ex) {
    Logger.getLogger(DownloadLoadiciousComputer.class.getName()).log(Level.SEVERE, null, ex);  
}

Es ist nur ein Testprojekt, deshalb erlaube und verwende ich nicht vertrauenswürdige Zertifikate mit dem Code:

TrustManager[] trustAllCerts = new TrustManager[]{
    new X509TrustManager() {

        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        public void checkClientTrusted(
                java.security.cert.X509Certificate[] certs, String authType) {
        }

        public void checkServerTrusted(
                java.security.cert.X509Certificate[] certs, String authType) {
        }
    }
};

try {

    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new java.security.SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {

    Logger.getLogger(DownloadManager.class.getName()).log(Level.SEVERE, null, e);
} 

Ich habe erfolgreich versucht, eine Verbindung zu https://google.com herzustellen . Wo ist meine Schuld?

Vielen Dank.

pvomhoff
quelle

Antworten:

304

Java 7 führte die SNI-Unterstützung ein, die standardmäßig aktiviert ist. Ich habe herausgefunden, dass bestimmte falsch konfigurierte Server im SSL-Handshake eine Warnung "Nicht erkannter Name" senden, die von den meisten Clients ignoriert wird ... mit Ausnahme von Java. Wie @ Bob Kerns erwähnt hat, weigern sich die Oracle-Ingenieure, diesen Fehler / diese Funktion zu "beheben".

Um dieses Problem zu umgehen, schlagen sie vor, die jsse.enableSNIExtensionEigenschaft festzulegen . Führen Sie Ihre App wie folgt aus, damit Ihre Programme ohne erneutes Kompilieren funktionieren:

java -Djsse.enableSNIExtension=false yourClass

Die Eigenschaft kann auch im Java-Code festgelegt werden, muss jedoch vor allen SSL-Aktionen festgelegt werden . Sobald die SSL-Bibliothek geladen wurde, können Sie die Eigenschaft ändern, dies hat jedoch keine Auswirkungen auf den SNI-Status . Verwenden Sie zum Deaktivieren von SNI zur Laufzeit (mit den oben genannten Einschränkungen):

System.setProperty("jsse.enableSNIExtension", "false");

Der Nachteil des Setzens dieses Flags besteht darin, dass SNI überall in der Anwendung deaktiviert ist. Um SNI zu nutzen und trotzdem falsch konfigurierte Server zu unterstützen:

  1. Erstellen Sie eine SSLSocketmit dem Hostnamen, zu dem Sie eine Verbindung herstellen möchten. Nennen wir das sslsock.
  2. Versuche zu rennen sslsock.startHandshake(). Dies wird blockiert, bis dies erledigt ist, oder es wird eine Ausnahme bei einem Fehler ausgelöst. Wenn ein Fehler aufgetreten ist startHandshake(), erhalten Sie die Ausnahmemeldung. Wenn dies gleich ist handshake alert: unrecognized_name, haben Sie einen falsch konfigurierten Server gefunden.
  3. Wenn Sie die unrecognized_nameWarnung erhalten haben (in Java schwerwiegend), versuchen Sie erneut, a zu öffnen SSLSocket, diesmal jedoch ohne Hostnamen. Dadurch wird SNI effektiv deaktiviert (schließlich geht es bei der SNI-Erweiterung darum, der ClientHello-Nachricht einen Hostnamen hinzuzufügen).

Für den Webscarab-SSL-Proxy implementiert dieses Commit das Fallback -Setup.

Lekensteyn
quelle
5
es funktioniert, danke! Der IntelliJ IDEA-Subversion-Client hatte den gleichen Fehler beim Herstellen einer Verbindung über HTTPS. Sie müssen nur die Datei idea.exe.vmoptions mit der folgenden Zeile aktualisieren: -Djsse.enableSNIExtension = false
Dima
2
Für Java Webstart verwenden Sie diese: javaws -J-Djsse.enableSNIExtension = false yourClass
Torsten
Ich hatte genau das gleiche Problem mit meinem Jersey-Client mit dem https-Restserver. Es stellte sich heraus, dass ich deinen Trick benutzt habe und es funktioniert hat !! Vielen Dank!
Shahshi15
4
Für diejenigen, die sich über Java 8 wundern, hat Oracle das Verhalten immer noch nicht geändert und verlangt vom Programmierer immer noch, Server abzufangen,
Lekensteyn
2
@Blauhirn Wenden Sie sich an Ihren Webhost-Support, er sollte seine Konfiguration korrigieren. Wenn sie Apache verwenden, suchen Sie nach Änderungen, die vorgenommen werden müssen.
Lekensteyn
89

Ich hatte das, was ich glaube, das gleiche Problem. Ich stellte fest, dass ich die Apache-Konfiguration anpassen musste, um einen Servernamen oder ServerAlias ​​für den Host einzuschließen.

Dieser Code ist fehlgeschlagen:

public class a {
   public static void main(String [] a) throws Exception {
      java.net.URLConnection c = new java.net.URL("https://mydomain.com/").openConnection();
      c.setDoOutput(true);
      c.getOutputStream();
   }
}

Und dieser Code hat funktioniert:

public class a {
   public static void main(String [] a) throws Exception {
      java.net.URLConnection c = new java.net.URL("https://google.com/").openConnection();
      c.setDoOutput(true);
      c.getOutputStream();
   }
}

Wireshark gab bekannt, dass während des TSL / SSL-Hallo die Warnmeldung (Stufe: Warnung, Beschreibung: Nicht erkannter Name), Server Hallo vom Server an den Client gesendet wurde. Es war jedoch nur eine Warnung. Java 7.1 antwortete dann sofort mit einer "Schwerwiegenden, Beschreibung: Unerwartete Nachricht". Ich gehe davon aus, dass die Java-SSL-Bibliotheken die Warnung vor nicht erkannten Namen nicht gerne sehen.

Aus dem Wiki zur Transport Layer Security (TLS):

112 Nicht erkannte Namenswarnung Nur TLS; Der Servername-Indikator des Clients hat einen Hostnamen angegeben, der vom Server nicht unterstützt wird

Dies führte mich zu einem Blick auf meine Apache-Konfigurationsdateien und ich stellte fest, dass das Hinzufügen eines Servernamens oder ServerAlias ​​für den von der Client- / Java-Seite gesendeten Namen ohne Fehler ordnungsgemäß funktionierte.

<VirtualHost mydomain.com:443>
  ServerName mydomain.com
  ServerAlias www.mydomain.com
David McLaughlin
quelle
3
Dies scheint ein Fehler in der TLS-Implementierung von Java zu sein.
Paŭlo Ebermann
1
Ich habe tatsächlich einen Bug dafür geöffnet. Ich habe diese Nummer zugewiesen (noch nicht sichtbar): bugs.sun.com/bugdatabase/view_bug.do?bug_id=7127374
eckes
1
Danke, das Hinzufügen ServerAliashat für mich funktioniert. Ich hatte den gleichen TLS-Alarm in Wireshark gesehen.
Jared Beck
2
Das hat auch bei mir funktioniert. (hätte besser funktioniert, wenn ich es geglaubt hätte und nicht auf einem anderen Weg auf die Jagd gegangen wäre)
Endbenutzer
10
@JosephShraibman, zu sagen, der Oracle-Mitarbeiter sei ein Idiot, ist unangemessen. Wenn Sie zwei ServerNameSekunden verwenden, antwortet Apache mit einer unrecognized_name Warnmeldung (die auch eine schwerwiegende Warnung sein kann). RFC 6066 sagt dies genau zu diesem Thema: " Es wird NICHT EMPFOHLEN, eine Warnung für nicht erkannten Warennamen (112) auf Warnungsebene zu senden, da das Verhalten des Clients als Reaktion auf Warnungen auf Warnungsebene nicht vorhersehbar ist. " Der einzige Fehler, den dieser Mitarbeiter gemacht hat, ist die Annahme, dass dies eine fatale Warnung war. Dies ist sowohl ein JRE-Fehler als auch ein Apache-Fehler.
Bruno
36

Sie können das Senden von SNI-Datensätzen mit der Systemeigenschaft jsse.enableSNIExtension = false deaktivieren.

Wenn Sie den Code ändern können, ist die Verwendung hilfreich SSLCocketFactory#createSocket()(ohne Host-Parameter oder mit angeschlossenem Socket). In diesem Fall wird keine Angabe des Servernamens gesendet.

eckes
quelle
11
Was so gemacht wird:System.setProperty ("jsse.enableSNIExtension", "false");
jn1kk
Ich habe festgestellt, dass das nicht immer funktioniert. Ich weiß nicht, warum es in einigen Fällen funktioniert und in anderen nicht.
Joseph Shraibman
2
Funktioniert für mich mit -Djsse.enableSNIExtension=false. Aber was macht es sonst noch? Ist es schädlich für den Rest der Sicherheit von Javas?
Ceving
2
Nein, dies bedeutet nur, dass einige Websites (insbesondere Webserver), die mehrere Hostnamen hinter einer gemeinsam genutzten IP verwenden, nicht wissen, welches Zertifikat gesendet werden soll. Aber wenn Ihre Java-App keine Verbindung zu Millionen von Websites herstellen muss, benötigen Sie diese Funktion nicht. Wenn Sie auf einen solchen Server stoßen, schlägt Ihre Zertifikatüberprüfung möglicherweise fehl und die Verbindung wird abgebrochen. Es wird also kein Sicherheitsproblem erwartet.
eckes
17

Dieser Fehler ist auch bei einem neuen Apache-Server-Build aufgetreten.

In unserem Fall bestand die Lösung darin, ein ServerAliasin dem zu definieren httpd.conf, das dem Hostnamen entsprach, zu dem Java eine Verbindung herstellen wollte. Unser ServerNamewurde auf den internen Hostnamen gesetzt. Unser SSL-Zertifikat verwendete den externen Hostnamen, aber das reichte nicht aus, um die Warnung zu vermeiden.

Um das Debuggen zu erleichtern, können Sie diesen ssl-Befehl verwenden:

openssl s_client -servername <hostname> -connect <hostname>:443 -state

Wenn es ein Problem mit diesem Hostnamen gibt, wird diese Nachricht oben in der Ausgabe gedruckt:

SSL3 alert read: warning:unrecognized name

Ich sollte auch beachten, dass wir diesen Fehler nicht erhalten haben, als wir diesen Befehl zum Herstellen einer Verbindung mit dem internen Hostnamen verwendet haben, obwohl er nicht mit dem SSL-Zertifikat übereinstimmt.

Scott McIntyre
quelle
6
Vielen Dank, dass Sie das Beispiel zur Reproduktion des Problems mit aufgenommen haben openssl. Es ist sehr hilfreich.
Sideshowbarker
2
Gibt es eine Möglichkeit für einen openssl-Client, den Namensunterschied zu erkennen, aus dem die Nachricht stammt SSL3 alert read: warning:unrecognized name? Ich sehe die Warnung gedruckt, aber die Ausgabe hilft mir nicht, diesen
Namensunterschied
Das funktioniert bei mir nicht. Getestet mit OpenSSL 1.0.1e-fips 11 Feb 2013, OpenSSL 1.0.2k-fips 26 Jan 2017und LibreSSL 2.6.5.
Greg Dubicki
15

Anstatt sich auf den Standardmechanismus für virtuelle Hosts in Apache zu verlassen, können Sie einen letzten virtuellen Catchall-Host definieren, der einen beliebigen Servernamen und einen Platzhalter ServerAlias ​​verwendet, z

ServerName catchall.mydomain.com
ServerAlias *.mydomain.com

Auf diese Weise können Sie SNI verwenden und Apache sendet die SSL-Warnung nicht zurück.

Dies funktioniert natürlich nur, wenn Sie alle Ihre Domänen einfach mit einer Platzhalter-Syntax beschreiben können.

Erik
quelle
Soweit ich weiß, sendet Apache diese Warnung nur, wenn der Client einen Namen verwendet, der weder als Servername noch als ServerAlias ​​konfiguriert ist. Wenn Sie also über ein *.mydomain.comPlatzhalterzertifikat verfügen, geben Sie entweder alle verwendeten Unterdomänen an oder verwenden Sie die Syntax für ServerAlias. Beachten Sie, dass Sie mehrere Aliase hinzufügen können ServerAlias, z ServerAlias *.mydomain.com mydomain.com *.myotherdomain.com.
Michael Paesold
13

Es sollte nützlich sein. So versuchen Sie einen SNI-Fehler in Apache HttpClient 4.4 erneut - der einfachste Weg, den wir gefunden haben (siehe HTTPCLIENT-1522 ):

public class SniHttpClientConnectionOperator extends DefaultHttpClientConnectionOperator {

    public SniHttpClientConnectionOperator(Lookup<ConnectionSocketFactory> socketFactoryRegistry) {
        super(socketFactoryRegistry, null, null);
    }

    @Override
    public void connect(
            final ManagedHttpClientConnection conn,
            final HttpHost host,
            final InetSocketAddress localAddress,
            final int connectTimeout,
            final SocketConfig socketConfig,
            final HttpContext context) throws IOException {
        try {
            super.connect(conn, host, localAddress, connectTimeout, socketConfig, context);
        } catch (SSLProtocolException e) {
            Boolean enableSniValue = (Boolean) context.getAttribute(SniSSLSocketFactory.ENABLE_SNI);
            boolean enableSni = enableSniValue == null || enableSniValue;
            if (enableSni && e.getMessage() != null && e.getMessage().equals("handshake alert:  unrecognized_name")) {
                TimesLoggers.httpworker.warn("Server received saw wrong SNI host, retrying without SNI");
                context.setAttribute(SniSSLSocketFactory.ENABLE_SNI, false);
                super.connect(conn, host, localAddress, connectTimeout, socketConfig, context);
            } else {
                throw e;
            }
        }
    }
}

und

public class SniSSLSocketFactory extends SSLConnectionSocketFactory {

    public static final String ENABLE_SNI = "__enable_sni__";

    /*
     * Implement any constructor you need for your particular application -
     * SSLConnectionSocketFactory has many variants
     */
    public SniSSLSocketFactory(final SSLContext sslContext, final HostnameVerifier verifier) {
        super(sslContext, verifier);
    }

    @Override
    public Socket createLayeredSocket(
            final Socket socket,
            final String target,
            final int port,
            final HttpContext context) throws IOException {
        Boolean enableSniValue = (Boolean) context.getAttribute(ENABLE_SNI);
        boolean enableSni = enableSniValue == null || enableSniValue;
        return super.createLayeredSocket(socket, enableSni ? target : "", port, context);
    }
}

und

cm = new PoolingHttpClientConnectionManager(new SniHttpClientConnectionOperator(socketFactoryRegistry), null, -1, TimeUnit.MILLISECONDS);
Shcheklein
quelle
Wenn du es so machst. Wie gehen Sie mit verifyHostname(sslsock, target)in SSLConnectionSocketFactory.createLayeredSocket? Da die targetZeichenfolge in eine leere Zeichenfolge geändert wird, verifyHostnamewird dies nicht erfolgreich sein. Vermisse ich hier etwas Offensichtliches?
Haozhun
2
Genau das habe ich gesucht, vielen Dank! Ich habe keine andere Möglichkeit gefunden, SNI und Server zu unterstützen, die gleichzeitig mit dieser Warnung "Nicht erkannter Name" antworten.
Korpe
Diese Lösung funktioniert, sofern Sie keinen Proxyserver verwenden.
Mrog
Nachdem ich gerade ein kurzes Debugging durch den Apache-Clientcode durchgeführt habe, beginnend mit verifyHostname (), kann ich nicht sehen, wie dies mit dem DefaultHostnameVerifier funktionieren kann. Ich vermute, dass für diese Lösung die Überprüfung des Hostnamens deaktiviert werden muss (z. B. mithilfe eines NoopHostnameVerifier). Dies ist KEINE gute Idee, da dadurch Man-in-the-Middle-Angriffe möglich sind.
FlyingSheep
11

Verwenden:

  • System.setProperty ("jsse.enableSNIExtension", "false");
  • Starten Sie Ihren Tomcat neu (wichtig)
Tomasz Janisiewicz
quelle
6

Ist auf dieses Problem mit Spring Boot und JVM 1.7 und 1.8 gestoßen. In AWS hatten wir nicht die Möglichkeit, den Servernamen und die ServerAlias ​​so zu ändern, dass sie übereinstimmen (sie sind unterschiedlich). Daher haben wir Folgendes getan:

In build.gradle haben wir Folgendes hinzugefügt:

System.setProperty("jsse.enableSNIExtension", "false")
bootRun.systemProperties = System.properties

Dadurch konnten wir das Problem mit dem "nicht erkannten Namen" umgehen.

Ray Hunter
quelle
5

Sie können dem Tool jarsigner.exe leider keine Systemeigenschaften zuweisen.

Ich habe den Fehler 7177232 eingereicht, auf den Fehler 7127374 von @eckes verwiesen und erklärt, warum er fälschlicherweise geschlossen wurde.

Bei meinem Fehler geht es speziell um die Auswirkungen auf das Jarsigner-Tool, aber möglicherweise führt dies dazu, dass der andere Fehler erneut geöffnet und das Problem ordnungsgemäß behoben wird.

UPDATE: Es stellt sich heraus, dass Sie dem Jarsigner-Tool Systemeigenschaften bereitstellen können. Dies ist nur nicht in der Hilfemeldung enthalten. Verwendenjarsigner -J-Djsse.enableSNIExtension=false

Bob Kerns
quelle
1
Danke Bob für das Follow-up. Leider versteht Oracle das Ganze immer noch nicht. Die SNI-Warnung ist nicht tödlich, sie kann tödlich sein. Die meisten typischen SSL-Clients (dh Browser) haben dies jedoch ignoriert, da es sich nicht um ein echtes Sicherheitsproblem handelt (da Sie das Serverzertifikat noch überprüfen müssen und falsche Endpunkte erkennen würden). Natürlich ist es traurig, dass eine Zertifizierungsstelle keine Einstellungen vornehmen kann einen ordnungsgemäß konfigurierten https-Server einrichten.
eckes
2
Tatsächlich stellt sich heraus, dass Sie dem Jarsigner-Tool Systemeigenschaften bereitstellen können. Dies ist nur nicht in der Hilfemeldung enthalten. Es wird in der Dokumentation behandelt. Blöd mich, dass ich dem Online-Text glaube. Natürlich benutzten sie dies als Entschuldigung dafür, es nicht zu reparieren.
Bob Kerns
Übrigens: Ich diskutiere dieses Problem derzeit auf security-dev @ openjdk und als ich es evaluierte, sah es so aus, als ob Symantec den GEOTrust-Zeitstempelserver repariert hat. Es akzeptiert jetzt die URL korrekt ohne Warnung. Aber ich denke immer noch, dass das behoben werden sollte. Wenn Sie einen Blick darauf werfen möchten, ein Test-Client- Projekt und die Diskussion :
eckes
3

Ich habe das gleiche Problem festgestellt und es stellte sich heraus, dass Reverse DNS nicht korrekt eingerichtet war. Es zeigte auf einen falschen Hostnamen für die IP. Nachdem ich Reverse DNS korrigiert und httpd neu gestartet habe, ist die Warnung verschwunden. (Wenn ich Reverse-DNS nicht korrigiere, hat das Hinzufügen von ServerName auch für mich geholfen)

user2888387
quelle
2

Mein VirtualHost's ServerNamewurde standardmäßig auskommentiert. Es funktionierte nach dem Kommentieren.

Aram Paronikyan
quelle
Hier gilt das gleiche. Servername fehlte.
Dark Star1
2

Wenn Sie einen Client mit Resttemplate erstellen, können Sie den Endpunkt nur wie folgt festlegen : https: // IP / path_to_service und die requestFactory festlegen.
Mit dieser Lösung müssen Sie TOMCAT oder Apache nicht neu starten:

public static HttpComponentsClientHttpRequestFactory requestFactory(CloseableHttpClient httpClient) {
    TrustStrategy acceptingTrustStrategy = new TrustStrategy() {
        @Override
        public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            return true;
        }
    };

    SSLContext sslContext = null;
    try {
        sslContext = org.apache.http.ssl.SSLContexts.custom()
                .loadTrustMaterial(null, acceptingTrustStrategy)
                .build();
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
    }   

    HostnameVerifier hostnameVerifier = new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };

    final SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext,hostnameVerifier);

    final Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
            .register("http", new PlainConnectionSocketFactory())
            .register("https", csf)
            .build();

    final PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
    cm.setMaxTotal(100);
    httpClient = HttpClients.custom()
            .setSSLSocketFactory(csf)
            .setConnectionManager(cm)
            .build();

    HttpComponentsClientHttpRequestFactory requestFactory =
            new HttpComponentsClientHttpRequestFactory();

    requestFactory.setHttpClient(httpClient);

    return requestFactory;
}
Alfredo
quelle
1

Ich bin auch auf dieses Problem beim Upgrade von Java 1.6_29 auf 1.7 gestoßen.

Alarmierend ist, dass mein Kunde in der Java-Systemsteuerung eine Einstellung entdeckt hat, die dieses Problem behebt.

Auf der Registerkarte "Erweitert" können Sie "SSL 2.0-kompatibles ClientHello-Format verwenden" aktivieren.

Dies scheint das Problem zu lösen.

Wir verwenden Java-Applets in einem Internet Explorer-Browser.

Hoffe das hilft.

Allan D.
quelle
0

Ich hatte das gleiche Problem mit einem Ubuntu Linux-Server, auf dem Subversion ausgeführt wurde, wenn über Eclipse zugegriffen wurde.

Es hat sich gezeigt, dass das Problem mit einer Warnung beim (erneuten) Start von Apache zu tun hat:

[Mon Jun 30 22:27:10 2014] [warn] NameVirtualHost *:80 has no VirtualHosts

... waiting [Mon Jun 30 22:27:11 2014] [warn] NameVirtualHost *:80 has no VirtualHosts

Dies ist auf einen neuen Eintrag in zurückzuführen ports.conf, bei dem NameVirtualHostneben der Richtlinie in eine weitere Richtlinie eingegeben wurde sites-enabled/000-default.

Nach dem Entfernen der Direktive ports.confwar das Problem verschwunden (natürlich nach dem Neustart von Apache).

Gerhard
quelle
0

Nur um hier eine Lösung hinzuzufügen. Dies kann für LAMP-Benutzer hilfreich sein

Options +FollowSymLinks -SymLinksIfOwnerMatch

Die oben erwähnte Zeile in der Konfiguration des virtuellen Hosts war der Schuldige.

Konfiguration des virtuellen Hosts bei Fehler

<VirtualHost *:80>
    DocumentRoot /var/www/html/load/web
    ServerName dev.load.com
    <Directory "/var/www/html/load/web">
        Options +FollowSymLinks -SymLinksIfOwnerMatch
        AllowOverride All
        Require all granted
        Order Allow,Deny
        Allow from All
    </Directory>
     RewriteEngine on
     RewriteCond %{SERVER_PORT} !^443$
     RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [NC,R=301,L]
</VirtualHost>

Arbeitskonfiguration

<VirtualHost *:80>
    DocumentRoot /var/www/html/load/web

   ServerName dev.load.com
   <Directory "/var/www/html/load/web">

        AllowOverride All

        Options All

        Order Allow,Deny

        Allow from All

    </Directory>

    # To allow authorization header
    RewriteEngine On
    RewriteCond %{HTTP:Authorization} ^(.*)
    RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

   # RewriteCond %{SERVER_PORT} !^443$
   # RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [NC,R=301,L]


</VirtualHost>
Greif
quelle
0

Hier ist eine Lösung für Appache httpclient 4.5.11. Ich hatte ein Problem mit dem Zertifikat, das den Platzhalter hat *.hostname.com. Es gab mir dieselbe Ausnahme zurück, aber ich sollte das Deaktivieren nach Eigenschaften nicht verwenden, System.setProperty("jsse.enableSNIExtension", "false");da es im Google-Standortclient einen Fehler gemacht hat.

Ich habe eine einfache Lösung gefunden (nur Socket modifizieren):

import io.micronaut.context.annotation.Bean;
import io.micronaut.context.annotation.Factory;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;

import javax.inject.Named;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket;
import java.io.IOException;
import java.util.List;

@Factory
public class BeanFactory {

    @Bean
    @Named("without_verify")
    public HttpClient provideHttpClient() {
        SSLConnectionSocketFactory connectionSocketFactory = new SSLConnectionSocketFactory(SSLContexts.createDefault(), NoopHostnameVerifier.INSTANCE) {
            @Override
            protected void prepareSocket(SSLSocket socket) throws IOException {
                SSLParameters parameters = socket.getSSLParameters();
                parameters.setServerNames(List.of());
                socket.setSSLParameters(parameters);
                super.prepareSocket(socket);
            }
        };

        return HttpClients.custom()
                .setSSLSocketFactory(connectionSocketFactory)
                .build();
    }


}
Andrew Sneck
quelle
-1

Es gibt eine einfachere Möglichkeit , einfach Ihren eigenen HostnamenVerifier zu verwenden, um bestimmten Verbindungen implizit zu vertrauen. Das Problem tritt bei Java 1.7 auf, wo SNI-Erweiterungen hinzugefügt wurden und Ihr Fehler auf eine Fehlkonfiguration des Servers zurückzuführen ist.

Sie können entweder "-Djsse.enableSNIExtension = false" verwenden, um SNI in der gesamten JVM zu deaktivieren, oder meinen Blog lesen, in dem ich erkläre, wie ein benutzerdefinierter Verifizierer über einer URL-Verbindung implementiert wird.

MagicDude4Eva
quelle