admin管理员组

文章数量:1122832

I am running Wordpress behind a proxy. The is_ssl() function in wp_includes/load.php will never be able to work in an environment like this because $_SERVER['HTTPS'] has no idea how the browser sees the page. All requests are normalized by the proxy.

I can make my site work by changing the is_ssl() function, but now, periodically, Wordpress "fixes" my fix when it does auto-updates.

What is the preferred way to deal with this situation? I am currently on v5.7.1 and I don't even see a way to disable updates. I would rather not disable updates anyhow.

How can I tell Wordpress that is_ssl() is always true, and keep it permanently throughout updates?

I am running Wordpress behind a proxy. The is_ssl() function in wp_includes/load.php will never be able to work in an environment like this because $_SERVER['HTTPS'] has no idea how the browser sees the page. All requests are normalized by the proxy.

I can make my site work by changing the is_ssl() function, but now, periodically, Wordpress "fixes" my fix when it does auto-updates.

What is the preferred way to deal with this situation? I am currently on v5.7.1 and I don't even see a way to disable updates. I would rather not disable updates anyhow.

How can I tell Wordpress that is_ssl() is always true, and keep it permanently throughout updates?

Share Improve this question asked May 10, 2021 at 19:53 OctopusOctopus 1531 gold badge1 silver badge5 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 10

You can't hook is_ssl() to override the result, and as you've noticed you can't edit WordPress Core itself or your changes will get lost if you're using built-in automatic updates.

So the usual approach - see the WordPress documentation - is to set $_SERVER['HTTPS'] = 'on';, which is the property is_ssl() tests. Add the following block to wp-config.php (which is preserved during updates), somewhere before the final require_once:

if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false) {
    $_SERVER['HTTPS'] = 'on';
}

This tests whether your reverse proxy added a header X-Forwarded-Proto: https to the proxied request and if it did it sets the HTTPS flag for WordPress, so that the SSL flag does try and reflect the original request. The Really Simple SSL plugin has a more comprehensive version of this that I've used too that tests more values from other proxies:

//Begin Really Simple SSL Load balancing fix
if ((isset($_ENV["HTTPS"]) && ("on" == $_ENV["HTTPS"]))
  || (isset($_SERVER["HTTP_X_FORWARDED_SSL"]) && (strpos($_SERVER["HTTP_X_FORWARDED_SSL"], "1") !== false))
  || (isset($_SERVER["HTTP_X_FORWARDED_SSL"]) && (strpos($_SERVER["HTTP_X_FORWARDED_SSL"], "on") !== false))
  || (isset($_SERVER["HTTP_CF_VISITOR"]) && (strpos($_SERVER["HTTP_CF_VISITOR"], "https") !== false))
  || (isset($_SERVER["HTTP_CLOUDFRONT_FORWARDED_PROTO"]) && (strpos($_SERVER["HTTP_CLOUDFRONT_FORWARDED_PROTO"], "https") !== false))
  || (isset($_SERVER["HTTP_X_FORWARDED_PROTO"]) && (strpos($_SERVER["HTTP_X_FORWARDED_PROTO"], "https") !== false))
  || (isset($_SERVER["HTTP_X_PROTO"]) && (strpos($_SERVER["HTTP_X_PROTO"], "SSL") !== false))
) {
  $_SERVER["HTTPS"] = "on";
}
//END Really Simple SSL

And there's an alternative approach here on StackOverflow where you can use Apache configuration to set HTTPS=1 instead if that's easier:

<IfModule mod_setenvif.c>
  SetEnvIf X-Forwarded-Proto "^https$" HTTPS
</IfModule>

rather than editing wp-config.

This is an older thread, but I like to share the solution.

Step 1: access DB > wp_options > siteurl : https://domain.com

Step 2: access DB > wp_options > home : https://domain.com

Step 3: edit /var/www/wordpress/wp-config.php >

  define('WP_SITEURL', 'https://domain.com');
  define('WP_HOME', 'https://domain.com');

and paste the code below to the next line:

 /** Fix for SSL behind Proxy **/
  $parsedUrl = parse_url(WP_HOME);
  $scheme = $parsedUrl['scheme'];
  if ($scheme == 'https') {$_SERVER['HTTPS'] = 'on';}
  else {$_SERVER['HTTPS'] = 'off';}

The other solutions (modifying your wp-config.php) do work but the real solution would be to address this at the webserver level.

If we're using Apache, you could add this to your VirtualHost:

<VirtualHost *:80>
  SetEnvIf X-Forwarded-Proto "^https$" HTTPS
</VirtualHost>

However, if you have a traditional reverse-proxy setup where your service (wordpress/apache) always returns http traffic and your reverse-proxy always returns https traffic to the calling client, a better solution is to add the following to your VirtualHost:

<VirtualHost *:80>
  ServerName https://example.com
</VirtualHost>

Having a https:// prefixed ServerName addresses the issue and Apache will automatically always set HTTPS to on. The difference between this and just using SetEnv HTTPS on is that this configuration gives other Apache mods information about your site and it can use it to behave properly.

For example, this bug (https://github.com/apache/httpd/pull/325) where the DirectorySlash enforcement behaviour returns a http:// prefix 301 redirect is solved when the ServerName is explicitly set like this.

本文标签: httpsHow do I handle SSL properly when WP is behind a reverse proxy