CreatorBlo
CreatorBlo

Reputation: 143

Cloudflare - 525 SSL handshake failed

I switched with my Domain to Cloudflare and now I'm trying to use CloudFlare's SSL Feature.

I already own a SSL cert from StartSSL so I would be possible to set the settings to 'Full (Strict)' but I don't want to so I turned it to 'Full'.

Now I'm getting 525 Errors, after a 'Retry for a live Version' everything is okay. But I'm getting this Error everytime.

Has anyone an idea ?

Thank you

Picture of my Error

Upvotes: 14

Views: 57257

Answers (6)

Talal Abbasi
Talal Abbasi

Reputation: 62

I encountered same issue particularly with wordpress instances which were behind load balancing and configured along reserve-proxy behind Cloudflare. Other web apps worked perfectly fine. But i face the issue partcularly with Wordpress with elementor build. It took time to fine different links reference and able to understand root causes.

It's been a week, I haven't encountered 525 error for timebeing. So here's steps:

  1. Cloudflare => Switch TLS/SSL to Full. (Strict is causing bug with securing connection. Firstly I think it could be PHP 8x version not adapting properly and secondly there's limitation of mixed content on this feature as per cloudflare. so don't waste time on Full (Strict) just create rule to disable it for wordpress url or disable it as globally. We will add some extra on later steps which could work as Full (Strict).
  2. Cloudflare => Switch to developement Mode. (To ensure we see testing bypassing the cloudflare cache.
  3. Cloudflare => Enable Always Use HTTPS. And disable port 80 redirect from local webserver apache/ngnix or loadbalancer. This simplifies the compatiblity.
  4. Cloudflare => Enable HTTP Strict Transport Security (HSTS). (Optional keep Preload disable)
  5. Cloudflare => Minimum TLS Version - 1.2
  6. Cloudflare => Enable TLS 1.3
  7. Cloudflare => Enable Automatic HTTPS Rewrites
  8. Cloudflare => If your wordpress has elementor plugin (ref https://elementor.com/help/elementor-and-cloudflare-rocket-loader/). Ensure to disable Rocketloader as per screenshot => https://i.sstatic.net/u4Cwl.png
  9. Cloudflare => Disable Rocketloader under Speed Optimaization section.
  10. Cloudflare => Create Content Security Policy with Cloudflare worker with following. This ensure that if 520 or if 525 error occurs due to any network fluatuation, request is re-requested by browser. If you are first time using cloudflare worker then have a look here https://developers.cloudflare.com/workers/get-started/guide/. This also ensure extra protection to have on cloudflare. I copied the 2x worker config below worker.js

export default {
    async fetch(request, env, ctx) {
      if (request.body) {
        // This request has a body, i.e. it's submitting some information to
        // the server, not just requesting a web page. If we wanted to be able
        // to retry such requests, we'd have to buffer the body so that we
        // can send it twice. That is expensive, so instead we'll just hope
        // that these requests (which are relatively uncommon) don't fail.
        // So we just pass the request to the server and return the response
        // nomally.
        return fetch(request);
      }
  
      // Try the request the first time.
      let response = await fetch(request);
      
      if (response.status == 520) {
        // The server returned status 525. Let's retry the request. But
        // we'll only retry once, since we don't want to get stuck in an
        // infinite retry loop.
  
        // Let's discard the previous response body. This is not strictly
        // required but it helps let the Workers Runtime know that it doesn't
        // need to hold open the HTTP connection for the failed request.
        await response.arrayBuffer();
  
        // OK, now we retry the request, and replace the response with the
        // new version.
         response = await fetch(request);
      }

      if (response.status == 525) {
        // The server returned status 525. Let's retry the request. But
        // we'll only retry once, since we don't want to get stuck in an
        // infinite retry loop.
  
        // Let's discard the previous response body. This is not strictly
        // required but it helps let the Workers Runtime know that it doesn't
        // need to hold open the HTTP connection for the failed request.
        await response.arrayBuffer();
  
        // OK, now we retry the request, and replace the response with the
        // new version.
         response = await fetch(request);
      }  
      return response;
    }
  }

worker2.js

export default {
    async fetch(request) {
      const DEFAULT_SECURITY_HEADERS = {
        /*
      Secure your application with Content-Security-Policy headers.
      Enabling these headers will permit content from a trusted domain and all its subdomains.
      @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
      "Content-Security-Policy": "default-src 'self' example.com *.example.com",
      */
      /*"Content-Security-Policy": "script-src 'unsafe-eval' 'unsafe-inline' https:",
        /*
      You can also set Strict-Transport-Security headers.
      These are not automatically set because your website might get added to Chrome's HSTS preload list.
      Here's the code if you want to apply it:
      "Strict-Transport-Security" : "max-age=63072000; includeSubDomains; preload",
      */
      /*"Strict-Transport-Security" : "max-age=63072000; includeSubDomains; preload",
        /*
      Permissions-Policy header provides the ability to allow or deny the use of browser features, such as opting out of FLoC - which you can use below:
      "Permissions-Policy": "interest-cohort=()",
      */
      /*"Permissions-Policy": "interest-cohort=()",
        /*
      X-XSS-Protection header prevents a page from loading if an XSS attack is detected.
      @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection
      */
        "X-XSS-Protection": "0",
        /*
      X-Frame-Options header prevents click-jacking attacks.
      @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
      */
        "X-Frame-Options": "SAMEORIGIN",
        /*
      X-Content-Type-Options header prevents MIME-sniffing.
      @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
      */
        "X-Content-Type-Options": "nosniff",
        "Referrer-Policy": "strict-origin-when-cross-origin",
        "Cross-Origin-Embedder-Policy": 'require-corp; report-to="default";',
        "Cross-Origin-Opener-Policy": 'same-site; report-to="default";',
        "Cross-Origin-Resource-Policy": "same-site",
      };
      const BLOCKED_HEADERS = [
        "Public-Key-Pins",
        "X-Powered-By",
        "X-AspNet-Version",
      ];
  
      let response = await fetch(request);
      let newHeaders = new Headers(response.headers);
  
      const tlsVersion = request.cf.tlsVersion;
      console.log(tlsVersion);
      // This sets the headers for HTML responses:
      if (
        newHeaders.has("Content-Type") &&
        !newHeaders.get("Content-Type").includes("text/html")
      ) {
        return new Response(response.body, {
          status: response.status,
          statusText: response.statusText,
          headers: newHeaders,
        });
      }
  
      Object.keys(DEFAULT_SECURITY_HEADERS).map((name) => {
        newHeaders.set(name, DEFAULT_SECURITY_HEADERS[name]);
      });
  
      BLOCKED_HEADERS.forEach((name) => {
        newHeaders.delete(name);
      });
  
      if (tlsVersion !== "TLSv1.2" && tlsVersion !== "TLSv1.3") {
        return new Response("You need to use TLS version 1.2 or higher.", {
          status: 400,
        });
      } else {
        return new Response(response.body, {
          status: response.status,
          statusText: response.statusText,
          headers: newHeaders,
        });
      }
    },
  };
  /* css*/
  async function handleRequest(request) {
    let resp = await fetch(request.url, request);
  
    let newResp = new Response(resp.body, {
      headers: resp.headers,
      status: resp.status
    })
  
    if (request.url.endsWith(".css")) {
      newResp.headers.set("Content-Type", "text/css");
    }
    if (request.url.endsWith(".js")) {
      newResp.headers.set("Content-Type", "text/javascript");
    }
    return newResp;
  }
  
  addEventListener("fetch", event => event.respondWith(handleRequest(event.request)))
  

  1. Wordpress webserver and loadbalancer - If you using apache, please ensure that 443 SSL/TLS Ciphersuits matches same on Cloudflare, Loadbalancer (Origin Server), Webserver (wordpress). Review this link https://developers.cloudflare.com/ssl/reference/cipher-suites/
  2. Configure SNI on webserver and Loadbalancer VS. Ensure re-encryption is enabled.
  3. Configure header on origin server (loadbalancer) with properly persistence mode header. (ref https://developers.cloudflare.com/fundamentals/get-started/reference/http-request-headers/#cf-connecting-ip)
  4. Please ensure that origin server is installed with Cloudflare CA RSA certificate. ECA Certification could be buggy, i disabled it in loadbalancer. (Ref: https://developers.cloudflare.com/ssl/origin-configuration/origin-ca/#cloudflare-origin-ca-root-certificate)
  5. Disable Empty headers in origin server (load balancer). Some wordpress plugin does create empty headers, if your origin server has global policy better to disable empty header request. or solution B ref: https://equalizedigital.com/accessibility-checker/empty-heading/#:~:text=How%20to%20find%20empty%20headers%20on%20your%20WordPress%20post%20or%20page,-First%2C%20install%20the&text=For%20any%20pages%20or%20posts,caused%20the%20error%20to%20appear.
  6. Use ssllabs.com/ssltest/ to test your wordpress. To ensure you are having A category.

There are some additional configuration depending on what type of loadbalancer you using between cloudflare and wordpress. But I think all forum, i have checked, above info seems to be missing. So I hope this helps.

Upvotes: 1

Amar Kumar
Amar Kumar

Reputation: 2646

Visit SSL/TLS tab in Cloudflare. Then:

  1. Switch Your SSL/TLS encryption mode to Flexible.
  2. Make sure to switch On "Always Use HTTPS" under "Edge Certificate" tab. enter image description here

This will transfer all your request from Http to Https automatically. And if you'll implement custom SSL certificate on your hosting server then this 525 error will automatically disappear without changing anything on Cloudflare.

Upvotes: 5

Felipe Lima
Felipe Lima

Reputation: 453

I went through the same problem today and found that (at least in my case) it was the lack of TLS v1.3

I had just made a server using nginx + php-fpm and a self signed ssl to use below CloudFlare proxy.

When I switched from the production server to this new one, it gave error 525.

I gave the command: curl -I https://your_server_public_ip/ and it returned the error:

error: 1408F10B: SSL routines: ssl3_get_record: wrong version number

This error is described in the CloudFlare community at: https://community.cloudflare.com/t/community-tip-fixing-error-525-ssl-handshake-failed/44256

There they advise turning off TLS v1.3 on the CloudFlare panel, but I decided to try installing it.

Using nginx is so easy that I don’t know why to have it shut down.

Only add TLSv1.3 like this-> ssl_protocols TLSv1.2 TLSv1.3; in your nginx/snippets/ssl-params.conf file (default Ubuntu 20 and 18) that will work and you still use the latest and most secure protocols.

Upvotes: 0

sndeep gochar
sndeep gochar

Reputation: 195

Change Cloudflare SSL/TLS encryption mode in to Flexible. it worked for me.

Upvotes: 13

muinh
muinh

Reputation: 605

Got the same problem a few days ago. Our DevOps contacted support and found out that Cloudflare changed certificate type or smth in that way. Asked to return everything back. That helped.

Upvotes: 1

BinaryEvolved
BinaryEvolved

Reputation: 920

A 525 error indicates that CloudFlare was unable to contact your origin server and create a SSL connection with it.

This can be due to:

  • Your servers not having matching or compatible SSL Ciphers
  • Your website may not have a certificate installed properly
  • Your website may not have a dedicated IP OR is not configured to use SNI

Attempt to contact your hosting provider for assistance to ensure that your SSL certificate is setup correctly. If you are using a control panel, a quick google search can help you find a install guide for that said control panel.

Upvotes: 5

Related Questions