CloudFlare Authenticated Origin Pulls on Nginx or Apache
By Pete Freitag
If you are using CloudFlare in front of your web server, it is a good idea to setup CloudFlare Authenticated Origin Pulls. When this is enabled and properly configured only CloudFlare will be able to connect to your origin web server directly.
nginx example
An example setup on nginx might require that you add something like this:
ssl_client_certificate /etc/cloudflare/cloudflare-origin-pull-ca.pem; ssl_verify_client on;
That's it, now only CloudFlare can connect to this nginx server. You'll of course need the cloudflare-origin-pull-ca.pem
file, more on that below.
Apache Example
On Apache the configuration in your VirtualHost might look like this:
SSLVerifyClient require SSLVerifyDepth 1 SSLCACertificateFile /etc/cloudflare/cloudflare-origin-pull-ca.pem
The cloudflare-origin-pull-ca.pem File
In both examples I'm referencing a file: /etc/cloudflare/cloudflare-origin-pull-ca.pem this is CloudFlare's CA Certificate which you can grab from their site docs (direct download link). This public CA certificate is used to sign the client certificate on CloudFlare's edge servers that is used when requesting your origin server. The ssl_verify_client on
or SSLVerifyClient require
instruct your web server to reject any connections that are not signed by the CA certificate.
Troubleshooting
While it is pretty straight forward to setup if you miss something you might see a 400 Bad Request error like this:
400 Bad Request
No required SSL certificate was sent
nginx
Here are some things you can check if you see that error:
- Make sure you have checked the Authenticated Origin Pulls checkbox in CloudFlare Dashboard under SSL/TLS then Origin Server.
- Make sure you have set your SSL/TLS encryption mode to "Full" or "Full (Strict)" in the CloudFlare Dashboard, it won't work if your encryption mode is set to Flexible or Off.
- Make sure you have restarted or reloaded the configuration on your web server
How CloudFlare Authenticated Origin Pulls works using mTLS
CloudFlare Authenticated Origin Pulls work by using Mutual TLS or mTLS. This means that both ends of the connection are authenticated by a certificate using public key cryptography. The sequence of events goes like this:
- End User Request is received by CloudFlare
- CloudFlare connects to your origin server
- Your origin server presents its TLS certificate
- CloudFlare verifies your origin server certificate (this can either be a valid TLS certificate issued by an authority like Let's Encrypt, or a certificate issued by CloudFlare in its dashboard for your origin under Origin Certificates)
- CloudFlare presents its TLS certificate
- Your origin server verifies the CloudFlare's certificate
- Your origin Server grants access to CloudFlare and communicate over an encrypted TLS channel
Uploading your own Authenticated Origin Pull Certificate
CloudFlare has updated their documentation with this warning:
Although Cloudflare provides you a certificate to easily configure zone-level authenticated origin pulls, this certificate is not exclusive to your account and only guarantees that a request is coming from the Cloudflare network. If you want more strict security, you should upload your own certificate.
I assume that the risk here is that a different CloudFlare account could also setup a hostname that points to your IP address. In this case CloudFlare would be making the request to your server. What happens next depends on how your web server is setup to handle a request for an unexpected hostname.
This means for Apache servers it is important to have a dummy default VirtualHost, and it needs to be the first VirtualHost in the Apache configuration. According to the Apache 2.4 docs:
If no matching ServerName or ServerAlias is found in the set of virtual hosts containing the most specific matching IP address and port combination, then the first listed virtual host that matches that will be used.
On nginx you'll want to make sure you have setup a default server, eg:
server { server_name _; listen 80 default_server; listen 443 ssl default_server; # uncomment if using ipv6 # listen [::]:80 default_server; # listen [::]:443 ssl default_server; ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem; ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key; #always return an error, use whaever code make sense return 404; }
If you do want to setup a custom certificate, it looks like you'll need at least a CloudFlare Pro account for this.
CloudFlare Authenticated Origin Pulls on Nginx or Apache was first published on January 27, 2022.