Cảnh báo bắt tay SSL: lỗi unrecognized_name kể từ khi nâng cấp lên Java 1.7.0


225

Tôi đã nâng cấp từ Java 1.6 lên Java 1.7 ngày hôm nay. Kể từ đó, xảy ra lỗi khi tôi cố gắng thiết lập kết nối với máy chủ web của mình qua SSL:

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)

Đây là mã:

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);  
}

Đây chỉ là một dự án thử nghiệm mà tại sao tôi cho phép và sử dụng các chứng chỉ không tin cậy với mã:

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);
} 

Tôi đã cố gắng kết nối với https://google.com . lỗi của tôi ở đâu

Cảm ơn.

Câu trả lời:


304

Java 7 giới thiệu hỗ trợ SNI được bật theo mặc định. Tôi đã phát hiện ra rằng một số máy chủ được định cấu hình sai gửi một cảnh báo "Tên không được nhận dạng" trong cái bắt tay SSL bị hầu hết các máy khách bỏ qua ... ngoại trừ Java. Như @Bob Kerns đã đề cập, các kỹ sư của Oracle từ chối "sửa" lỗi / tính năng này.

Như cách giải quyết, họ đề nghị thiết lập jsse.enableSNIExtensiontài sản. Để cho phép các chương trình của bạn hoạt động mà không cần biên dịch lại, hãy chạy ứng dụng của bạn dưới dạng:

java -Djsse.enableSNIExtension=false yourClass

Thuộc tính cũng có thể được đặt trong mã Java, nhưng nó phải được đặt trước bất kỳ hành động SSL nào . Khi thư viện SSL đã được tải, bạn có thể thay đổi thuộc tính, nhưng nó sẽ không có bất kỳ ảnh hưởng nào đến trạng thái SNI . Để tắt SNI khi chạy (với các giới hạn đã nói ở trên), hãy sử dụng:

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

Nhược điểm của việc đặt cờ này là SNI bị vô hiệu hóa ở mọi nơi trong ứng dụng. Để sử dụng SNI và vẫn hỗ trợ các máy chủ bị định cấu hình sai:

  1. Tạo một SSLSockettên máy chủ bạn muốn kết nối. Hãy đặt tên này sslsock.
  2. Cố gắng chạy sslsock.startHandshake(). Điều này sẽ chặn cho đến khi nó được thực hiện hoặc đưa ra một ngoại lệ về lỗi. Bất cứ khi nào xảy ra lỗi startHandshake(), nhận thông báo ngoại lệ. Nếu nó bằng handshake alert: unrecognized_name, thì bạn đã tìm thấy một máy chủ bị cấu hình sai.
  3. Khi bạn đã nhận được unrecognized_namecảnh báo (gây tử vong trong Java), hãy thử mở lại SSLSocket, nhưng lần này không có tên máy chủ. Điều này vô hiệu hóa SNI (xét cho cùng, tiện ích mở rộng SNI là về việc thêm tên máy chủ vào tin nhắn ClientHello).

Đối với proxy SSL Webscarab, cam kết này thực hiện cài đặt dự phòng.


5
nó hoạt động, cảm ơn! Máy khách lật đổ IntelliJ IDEA có cùng lỗi khi kết nối qua HTTPS. Chỉ cần cập nhật tệp idea.exe.vmoptions với dòng: -Djsse.enableSNIExtension = false
Dima

2
Đối với java webstart, hãy sử dụng cái này: javaws -J-Djsse.enableSNIExtension = false yourClass
Torsten

Tôi đã có cùng một vấn đề với khách hàng Jersey của tôi với máy chủ nghỉ ngơi https. Hóa ra tôi đã sử dụng mánh khóe của bạn và nó đã hoạt động !! cảm ơn!
shahshi15

4
Đối với những người thắc mắc về Java 8, Oracle vẫn không thay đổi hành vi và vẫn yêu cầu lập trình viên bắt các máy chủ không hỗ trợ SNI: docs.oracle.com/javase/8/docs/technotes/guides/security/jsse /
Lọ

2
@Blauhirn Liên hệ với bộ phận hỗ trợ webhost của bạn, họ sẽ sửa cấu hình của họ. Nếu họ sử dụng Apache, hãy xem qua một số thay đổi cần thực hiện.
Lekensteyn

89

Tôi đã có những gì tôi tin rằng vấn đề tương tự là. Tôi thấy rằng tôi cần điều chỉnh cấu hình Apache để bao gồm ServerName hoặc ServerAlias ​​cho máy chủ.

Mã này không thành công:

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();
   }
}

Và mã này đã hoạt động:

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 tiết lộ rằng trong TSL / SSL Xin chào Cảnh báo cảnh báo (Cấp độ: Cảnh báo, Mô tả: Tên không được nhận dạng), Máy chủ Hello đã được gửi từ máy chủ đến máy khách. Tuy nhiên, đó chỉ là một cảnh báo, Java 7.1 đã trả lời ngay lập tức bằng "Thông báo gây tử vong, mô tả: Tin nhắn bất ngờ", mà tôi cho rằng có nghĩa là các thư viện Java SSL không muốn thấy cảnh báo về tên không được nhận dạng.

Từ Wiki về Bảo mật lớp vận chuyển (TLS):

112 TLS cảnh báo tên không được công nhận; Chỉ báo tên máy chủ của máy khách chỉ định tên máy chủ không được máy chủ hỗ trợ

Điều này khiến tôi xem xét các tệp cấu hình Apache của mình và tôi thấy rằng nếu tôi thêm ServerName hoặc ServerAlias ​​cho tên được gửi từ phía máy khách / java, nó hoạt động chính xác mà không có bất kỳ lỗi nào.

<VirtualHost mydomain.com:443>
  ServerName mydomain.com
  ServerAlias www.mydomain.com

3
Điều này trông giống như một lỗi trong triển khai TLS của Java.
Paŭlo Ebermann

1
Tôi thực sự mở một lỗi cho việc này. Tôi đã nhận được số này được chỉ định (chưa hiển thị): bug.sun.com/ormsdatabase/view_orms.do?orms_id=7127374
eckes

1
Cảm ơn, thêm một ServerAliascông việc cho tôi. Tôi đã thấy cảnh báo TLS tương tự trong Wireshark.
Jared Beck

2
Điều này cũng làm việc cho tôi. (sẽ hoạt động tốt hơn nếu tôi tin và không đi săn một con đường khác)
người dùng cuối

10
@JosephShraibman, nói rằng nhân viên của Oracle là một thằng ngốc là không phù hợp. Khi bạn sử dụng hai ServerNamegiây, Apache sẽ phản hồi bằng một unrecognized_name cảnh báo (cũng có thể là cảnh báo gây tử vong ). RFC 6066 nói chính xác điều này về chủ đề này: " KHÔNG ĐƯỢC KHUYẾN NGHỊ gửi cảnh báo không nhận dạng được cấp cảnh báo (112), bởi vì hành vi của khách hàng khi phản ứng với cảnh báo ở mức cảnh báo là không thể đoán trước. ". Sai lầm duy nhất của nhân viên này là cho rằng đây là một cảnh báo nghiêm trọng . Đây là một lỗi JRE nhiều như nó là một lỗi của Apache.
Bruno

36

Bạn có thể vô hiệu hóa việc gửi các bản ghi SNI với thuộc tính Hệ thống jsse.enableSNIExtension = false.

Nếu bạn có thể thay đổi mã, nó sẽ giúp sử dụng SSLCocketFactory#createSocket()(không có tham số máy chủ hoặc với ổ cắm được kết nối). Trong trường hợp này, nó sẽ không gửi dấu hiệu server_name.


11
Điều này được thực hiện như thế này:System.setProperty ("jsse.enableSNIExtension", "false");
jn1kk

Tôi đã thấy rằng không phải lúc nào cũng làm việc. Tôi không biết tại sao nó hoạt động trong một số trường hợp chứ không phải những người khác.
Joseph Shraibman

2
Làm việc cho tôi với -Djsse.enableSNIExtension=false. Nhưng nó làm gì khác? Nó có hại cho phần còn lại của bảo mật Javas không?
ceving

2
Không, điều đó chỉ có nghĩa là một số trang web (đặc biệt là các máy chủ web) sử dụng tên máy chủ đa dạng đằng sau một IP được chia sẻ không biết phải gửi chứng chỉ nào. Nhưng trừ khi ứng dụng java của bạn phải kết nối với hàng triệu trang web, bạn sẽ không cần tính năng đó. Nếu bạn gặp một máy chủ như vậy, xác thực chứng chỉ của bạn có thể bị lỗi và hủy kết nối. Vì vậy, không có vấn đề bảo mật dự kiến.
eckes

17

Chúng tôi cũng gặp phải lỗi này khi xây dựng máy chủ Apache mới.

Khắc phục trong trường hợp của chúng tôi là xác định một ServerAliastrong httpd.confđó tương ứng với tên máy chủ mà Java đang cố gắng kết nối. Chúng tôi ServerNameđã được đặt thành tên máy chủ nội bộ. Chứng chỉ SSL của chúng tôi đã sử dụng tên máy chủ bên ngoài, nhưng điều đó là không đủ để tránh cảnh báo.

Để giúp gỡ lỗi, bạn có thể sử dụng lệnh ssl này:

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

Nếu có vấn đề với tên máy chủ đó, thì nó sẽ in thông báo này ở gần đầu ra:

SSL3 alert read: warning:unrecognized name

Tôi cũng cần lưu ý rằng chúng tôi không gặp phải lỗi đó khi sử dụng lệnh đó để kết nối với tên máy chủ nội bộ, mặc dù nó không khớp với chứng chỉ SSL.


6
Cảm ơn đã bao gồm ví dụ về cách tái tạo vấn đề bằng cách sử dụng openssl. Nó rất hữu ích.
sIDIAbarker

2
Có cách nào để máy khách openssl thấy sự khác biệt về tên bắt nguồn từ thông báo SSL3 alert read: warning:unrecognized namekhông? Tôi thấy cảnh báo được in, nhưng đầu ra không giúp tôi thực sự thấy sự khác biệt về cách đặt tên này
mox601

Điều này không làm việc cho tôi. Đã thử nghiệm với OpenSSL 1.0.1e-fips 11 Feb 2013, OpenSSL 1.0.2k-fips 26 Jan 2017LibreSSL 2.6.5.
Greg Dubicki

15

Thay vì dựa vào cơ chế máy chủ ảo mặc định trong apache, bạn có thể định nghĩa một virtualhost bắt cuối sử dụng ServerName tùy ý và ServerAlias ​​ký tự đại diện, vd

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

Theo cách đó, bạn có thể sử dụng SNI và apache sẽ không gửi lại cảnh báo SSL.

Tất nhiên, điều này chỉ hoạt động nếu bạn có thể mô tả tất cả các tên miền của mình một cách dễ dàng bằng cú pháp ký tự đại diện.


Theo tôi hiểu, apache chỉ gửi cảnh báo này trong trường hợp máy khách sử dụng tên không được cấu hình là ServerName hoặc ServerAlias. Vì vậy, nếu bạn có chứng chỉ thẻ hoang dã, hãy chỉ định tất cả các tên miền phụ được sử dụng hoặc sử dụng *.mydomain.comcú pháp cho ServerAlias. Lưu ý rằng bạn có thể thêm nhiều bí danh bằng cách sử dụng ServerAlias, ví dụ ServerAlias *.mydomain.com mydomain.com *.myotherdomain.com.
Michael Paesold

13

Nó sẽ hữu ích. Để thử lại lỗi SNI trong Apache HttpClient 4.4 - cách dễ nhất mà chúng tôi đã đưa ra (xem 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;
            }
        }
    }
}

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);
    }
}

cm = new PoolingHttpClientConnectionManager(new SniHttpClientConnectionOperator(socketFactoryRegistry), null, -1, TimeUnit.MILLISECONDS);

Nếu bạn làm theo cách này. Làm thế nào để bạn đối phó với verifyHostname(sslsock, target)trong SSLConnectionSocketFactory.createLayeredSocket? Vì chuỗi targetđược thay đổi thành chuỗi rỗng, verifyHostnamesẽ không thành công. Tôi có thiếu một cái gì đó rõ ràng ở đây?
Haozhun

2
Đây là chính xác, những gì tôi đang tìm kiếm, cảm ơn bạn rất nhiều! Tôi đã không tìm thấy bất kỳ cách nào khác để hỗ trợ SNI và các máy chủ phản hồi với cảnh báo "không được nhận dạng" này cùng một lúc.
korpe

Giải pháp này hoạt động, trừ khi bạn đang sử dụng máy chủ proxy.
mrog

Vừa thực hiện một quá trình gỡ lỗi nhanh thông qua mã máy khách Apache, bắt đầu với verifyhostname (), tôi không thể thấy cách thức này có thể hoạt động bằng cách sử dụng DefaulthostnameVerifier. Tôi nghi ngờ rằng giải pháp này yêu cầu xác minh Tên máy chủ bị vô hiệu hóa (ví dụ: sử dụng NoophostnameVerifier), đây không phải là ý kiến ​​hay vì nó cho phép các cuộc tấn công trung gian.
FlyingSheep

11

Sử dụng:

  • System.setProperty ("jsse.enableSNIExtension", "false");
  • Khởi động lại Tomcat của bạn (quan trọng)

6

Chạy vào vấn đề này với khởi động mùa xuân và jvm 1.7 và 1.8. Trên AWS, chúng tôi không có tùy chọn thay đổi ServerName và ServerAlias ​​để khớp (chúng khác nhau) nên chúng tôi đã làm như sau:

Trong build.gradle, chúng tôi đã thêm vào như sau:

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

Điều đó cho phép chúng tôi bỏ qua vấn đề với "Tên không được nhận dạng".


5

Thật không may, bạn không thể cung cấp các thuộc tính hệ thống cho công cụ jarsigner.exe.

Tôi đã gửi lỗi 7177232 , tham khảo khuyết điểm 7127374 của @eckes và giải thích lý do tại sao nó bị đóng do lỗi.

Khiếm khuyết của tôi đặc biệt là về tác động đối với công cụ jarsigner, nhưng có lẽ nó sẽ dẫn họ mở lại các khiếm khuyết khác và giải quyết vấn đề một cách đúng đắn.

CẬP NHẬT: Trên thực tế, hóa ra bạn CÓ THỂ cung cấp các thuộc tính hệ thống cho công cụ Jarsigner, nó chỉ không có trong thông báo trợ giúp. Sử dụngjarsigner -J-Djsse.enableSNIExtension=false


1
Cảm ơn Bob đã theo dõi. Đáng buồn thay, Oracle vẫn không hiểu toàn bộ. Cảnh báo SNI không gây tử vong, nó có thể gây tử vong. Nhưng hầu hết các máy khách SSL điển hình (ví dụ như trình duyệt) đã chọn bỏ qua vì đây không phải là vấn đề bảo mật thực sự (vì bạn vẫn cần kiểm tra chứng chỉ máy chủ và sẽ phát hiện các điểm cuối sai). lên một máy chủ https được cấu hình đúng.
eckes

2
Trên thực tế, hóa ra bạn CÓ THỂ cung cấp các thuộc tính hệ thống cho công cụ Jarsigner, nó chỉ không có trong thông báo trợ giúp. Nó được đề cập trong các tài liệu. Ngớ ngẩn tôi vì tin vào văn bản trực tuyến. Tất nhiên, họ đã sử dụng điều này như một cái cớ để không sửa nó.
Bob Kerns

BTW: Tôi hiện đang thảo luận về vấn đề này trên security-dev @ openjdk và hiện tại tôi đang đánh giá nó, có vẻ như Symantec đã sửa máy chủ đánh dấu thời gian GEOTrust, hiện tại nó chấp nhận chính xác URL mà không có cảnh báo. Nhưng tôi vẫn nghĩ rằng nên sửa. Nếu bạn muốn có một cái nhìn, một dự án khách hàng thử nghiệmthảo luận :
eckes

3

Tôi gặp vấn đề tương tự và hóa ra dns ngược không được thiết lập chính xác, nó chỉ ra tên máy chủ sai cho IP. Sau khi tôi sửa dns ngược và khởi động lại httpd, cảnh báo sẽ biến mất. (nếu tôi không sửa dns ngược, việc thêm ServerName cũng đã giúp tôi)


2

My VirtualHost's ServerNameđã nhận xét ra theo mặc định. Nó đã làm việc sau khi không chú ý.


Tương tự ở đây. Tên máy chủ bị thiếu.
Dark Star1

2

Nếu bạn đang xây dựng một ứng dụng khách với Resttemplate, bạn chỉ có thể đặt điểm cuối như thế này: https: // IP / path_to_service và đặt requestFactory.
Với giải pháp này, bạn không cần phải RESTART TOMCAT hoặc Apache của mình:

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;
}

1

Tôi cũng đã gặp vấn đề này trong khi nâng cấp từ Java 1.6_29 lên 1.7.

Đáng báo động, khách hàng của tôi đã phát hiện ra một cài đặt trong bảng điều khiển Java để giải quyết vấn đề này.

Trong Tab Nâng cao, bạn có thể kiểm tra 'Sử dụng định dạng ClientHello tương thích SSL 2.0'.

Điều này dường như để giải quyết vấn đề.

Chúng tôi đang sử dụng các applet Java trong trình duyệt Internet Explorer.

Hi vọng điêu nay co ich.


0

Tôi gặp vấn đề tương tự với máy chủ Ubuntu Linux chạy lật đổ khi được truy cập qua Eclipse.

Nó đã chỉ ra rằng vấn đề phải làm với một cảnh báo khi Apache (tái) bắt đầu:

[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

Điều này là do một mục mới ports.conf, trong đó một lệnh khác NameVirtualHostđược nhập cùng với chỉ thị trong sites-enabled/000-default.

Sau khi gỡ bỏ lệnh này ports.conf, vấn đề đã biến mất (sau khi khởi động lại Apache, một cách tự nhiên)


0

Chỉ cần thêm một giải pháp ở đây. Điều này có thể giúp cho người dùng LAMP

Options +FollowSymLinks -SymLinksIfOwnerMatch

Dòng được đề cập ở trên trong cấu hình máy chủ ảo là thủ phạm.

Cấu hình máy chủ ảo khi có lỗi

<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>

Cấu hình làm việc

<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>

0

Đây là giải pháp cho Appache httpclient 4.5.11. Tôi đã có vấn đề với cert có chủ đề ký tự đại diện *.hostname.com. Nó trả lại cho tôi ngoại lệ tương tự, nhưng tôi không sử dụng việc vô hiệu hóa bởi tài sản System.setProperty("jsse.enableSNIExtension", "false");vì nó gây ra lỗi trong ứng dụng khách vị trí của Google.

Tôi tìm thấy giải pháp đơn giản (chỉ sửa đổi ổ cắm):

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();
    }


}

-1

Có một cách dễ dàng hơn khi bạn chỉ cần sử dụng HostnameVerifier của riêng mình để hoàn toàn tin tưởng một số kết nối nhất định. Vấn đề xảy ra với Java 1.7 trong đó các phần mở rộng SNI đã được thêm vào và lỗi của bạn là do cấu hình sai của máy chủ.

Bạn có thể sử dụng "-Djsse.enableSNIExtension = false" để vô hiệu hóa SNI trên toàn bộ JVM hoặc đọc blog của tôi nơi tôi giải thích cách triển khai trình xác minh tùy chỉnh trên đầu kết nối URL.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.