Skip to content

Backgrounds

How-to Guides

Technical References

Configure a reverse proxy

A reverse proxy is a server that sits between the end-user requesting information from your site and the VIP application that serves the content. Most VIP applications do not require them, but if yours does, there are a few technical requirements and considerations to take into account before you implement one.

How to set up your server

The more you can tell us about your proxy server, the better we can support you in connecting it to VIP.

Our preferred method of implementing a reverse proxy setup is as follows:

  • The VIP Go domain and URL structure matches the incoming request. That is, if the user requested example.com/blog the resource VIP will return is example.com/blog.
  • The reverse proxy should set a True-Client-IP HTTP request header with the IP of the end-user.
  • The reverse proxy should set an X-VIP-Proxy-Verification header with an agreed alphanumeric secret string as the value (contact us to agree on and set this string).

Sending the X-VIP-PROXY-VERIFICATION header along with TRUE-CLIENT-IP from the proxy will allow us to verify, via the secret key previously shared with us and saved in the site’s configuration on our end, that the request came via the reverse proxy server, and that the REMOTE_ADDR value should be fixed with the TRUE-CLIENT-IP value. This value is used in logs, and to identify proxied Automattic staff who need to support your site. Ensure that these headers are Incoming headers, not Outgoing. The following code must then be used in the site’s vip-config.php file:

$proxy_lib = ABSPATH . '/wp-content/mu-plugins/lib/proxy/ip-forward.php';
if ( ! empty( $_SERVER['HTTP_TRUE_CLIENT_IP'] )
    && ! empty( $_SERVER['HTTP_X_VIP_PROXY_VERIFICATION'] )
    && file_exists( $proxy_lib ) ) {
    require_once $proxy_lib;
	// phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Validated in the function call.
    Automattic\VIP\Proxy\fix_remote_address_with_verification_key(
        $_SERVER['HTTP_TRUE_CLIENT_IP'],
        $_SERVER['HTTP_X_VIP_PROXY_VERIFICATION']
    );
	// phpcs:enable
}
  • Cloudflare Users: The TRUE-CLIENT-IP header is only available on Cloudflare Enterprise. If using Cloudflare, but not the Cloudflare Enterprise package, then you can use the CF-Connecting-IP header instead, which is exactly the same value under a different key. Amend the above code snippet and change both instances of the string HTTP_TRUE_CLIENT_IP to HTTP_CF_CONNECTING_IP.
  • Also ensure that any web application firewalls or other intermediary services allow access from VIP’s IP addresses, Jetpack’s IP addresses, and your application’s xmlrpc.php endpoint.
  • Finally, if you would like to send custom headers to help you test the proxy application, you may do so. VIP will not reject these requests.

How VIP will set up your application

  • Set the primary domain for the application to the production domain (http://www.example.com). This is so that requests returned back to the proxy server have the production domain. For multisite installations, see our documentation on special considerations for mapping domains.
  • Replace all instances of the VIP convenience domain with the production domain.
  • Map and issue TLS Certificates for the domain you provided for the VIP application.

How it works

Using the scenario where you want to host a VIP application at http://www.example.com/blog:

Alternate implementations

If a X-VIP-Proxy-Verification header cannot be set, the proxy can be verified by using an IP allow list and passing the client IP in the header True-Client-IP. Please note that the allow list must be kept up to date.

This implementation assumes a file vip-config/remote-proxy-ips.php, which contains an array of proxy IP addresses. The contents of the file should be similar to the example below:

<?php
// A constant defining an array of allowed IP addresses and/or CIDRs
// which equate to the possible IP addresses of your Remote Proxy
define( 'MY_PROXY_IP_ALLOW_LIST', [
    '1.2.3.4/20',
    '5.6.7.8/20',
    '2.3.4.5',
] );

The IPs can be provided as fully qualified IPv4 or IPv6 addresses, or in CIDR notation.
Then, the following code in vip-config/vip-config.php checks the Reverse Proxy’s IP address matches the allowed list, extracts the end user’s IP address from the True-Client-IP HTTP Header, and forwards the End User’s real IP address as REMOTEADDR:

$proxy_lib = ABSPATH . '/wp-content/mu-plugins/lib/proxy/ip-forward.php'; 
if ( ! empty( $_SERVER['HTTP_TRUE_CLIENT_IP'] ) && file_exists( $proxy_lib ) ) { 
    require_once( __DIR__ . '/remote-proxy-ips.php' ); 
    require_once( $proxy_lib ); 
 
    Automattic\VIP\Proxy\fix_remote_address( 
        $_SERVER['HTTP_TRUE_CLIENT_IP'], 
        $_SERVER['HTTP_X_FORWARDED_FOR'],
        MY_PROXY_IP_ALLOW_LIST 
        ); 
} 

Validating your proxy configuration

We encourage you to test your proxy configuration extensively leading up to launch.

Using cURL

One way to validate the reverse proxy is to configure the proxy and use curl to send a request to a URI that you expect to be forwarded to VIP and inspect the response headers. You should see x-hacker, x-powered-by, and other headers sent by VIP alongside the headers sent by the proxy server.

If example.com is your proxy server and the VIP application is at example.com/blog/ when you run curl -I https://example.com/blog/ you should see x-powered-by: WordPress VIP <https://wpvip.com&gt; and the headers identifying the proxy server.

Using a staging server

Another strategy for testing is to configure a staging proxy server for the routes you intend to set in production. If you have staging.example.com you can point staging.example.com/blog/ to the VIP application. If you would like to do this please notify VIP with the following:

  • The domain name of your staging server (staging.example.com)
  • When you would like to begin testing

VIP will map the domain and configure TLS certificates once DNS records are in place. Once you’re ready to start testing we can search-replace for the go-vip.co or go-vip.net convenience domain. When you’re ready to launch, you need only to replicate the proxy configuration on your production server.

Obtaining a TLS certificate

Let’s Encrypt issues a TLS certificate after verifying a domain’s ownership using what’s known as an ACME challenge. If you are using a reverse proxy or otherwise not pointing your DNS directly to VIP, then your configuration may cause the ACME challenge to fail.

To meet the ACME challenge’s requirements, your reverse proxy must point requests for /.well-known/acme-challenge/* (where * is a wildcard representing any string) to VIP. You can confirm your proxy’s configuration using the curl command. Here’s an example of a positive response that would meet the ACME challenge:

$ curl -I http://www.example.com/.well-known/acme-challenge/fdfxcxvdz
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 22 Mar 2021 15:38:12 GMT
Content-Type: text/plain;charset=utf-8
Connection: keep-alive
Vary: Accept-Encoding
Vary: Cookie

Note that the reverse proxy must not add any query parameters on the end of the acme-challenge URL. For example, if the reverse proxy adds ?sslEnabled=true to the end of the acme-challenge string, provisioning a Let’s Encrypt certificate will fail.

In addition to your proxy’s own security measures, validating the ACME challenge will ensure that the connection from your proxy to the VIP servers is secure. If you prefer to not adjust your proxy settings or to not use Let’s Encrypt, you may alternatively procure a custom TLS certificate from a third-party provider.

Last updated: July 18, 2021