Cloudflare and nginx setup howto?

I’m in the process of transitioning from Google’s deprecated Domains => Squarespace (ugh) => Cloudflare and am running into some issues related to getting Cloudflare to front my nginx webserver. I have a few questions that I’d appreciated some layman’s answers for…

SSL - what is the minimal setup on the CF and nginx sides for web requests to work ? I’m under the impression that CF does the SSL stuff automagically so I can simply leave nginx listening on tcp/80 only and CF will handle the SSL part quietly behind the scenes.

DNS - what is an example for a minimal domain with MX records and DNS records pointing to a public ip address for that domain’s webserver ?


  • I have A and AAAA records for mydomain, www.mydomain, alias2.mydomain pointing to the public ipv4 and ipv6 addresses for my AWS VM hosting the nginx server

  • I previously had LetsEncrypt doing the SSL on the nginx side, but after my domain transitioned to CF it seemed necessary to go back to a no SSL setup on the nginx side, so now the webserver listens only on port 80 currently. I set CF to Flexible which did help somewhat.

  • checking DNS by running ‘host’ vs. mydomain, www.mydomain, and alias2.mydomain all returns the same answers for ip addresses, with the domain returning the MX records as well. So I think that DNS is set up correctly

What works and what fails:

  • a curl to http[s]://mydomain or similarly alias2.mydomain works ok, but there is no response running curl to www.mydomain for either http or https.

So I guess I’m asking if there’s something magical in the www.mydomain alias somehow that I have to do something special to enable ?

Any ideas ?

Secondary question is related to going tcp/443 only on the nginx side. I’d like to disable tcp/80 there if I could get it to work end to end, but that’s a nice to have. If there are any howtos for that please let me know.

Pointers appreciated !!!

A curl -vvv example that failed follows, with the ip addresses etc. obfuscated a little…

curl https://www.mydomain/ -vvvv

  • Trying 2606:1234:1234::6815:7ce:443…
  • Connected to www.mydomain (2606:1234:1234::6815:7ce) port 443 (#0)
  • ALPN, offering h2
  • ALPN, offering http/1.1
  • CAfile: /etc/ssl/certs/ca-certificates.crt
  • CApath: /etc/ssl/certs
  • TLSv1.0 (OUT), TLS header, Certificate Status (22):
  • TLSv1.3 (OUT), TLS handshake, Client hello (1):
  • TLSv1.2 (IN), TLS header, Certificate Status (22):
  • TLSv1.3 (IN), TLS handshake, Server hello (2):
  • TLSv1.2 (IN), TLS header, Finished (20):
  • TLSv1.2 (IN), TLS header, Supplemental data (23):
  • TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
  • TLSv1.3 (IN), TLS handshake, Certificate (11):
  • TLSv1.3 (IN), TLS handshake, CERT verify (15):
  • TLSv1.3 (IN), TLS handshake, Finished (20):
  • TLSv1.2 (OUT), TLS header, Finished (20):
  • TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
  • TLSv1.2 (OUT), TLS header, Supplemental data (23):
  • TLSv1.3 (OUT), TLS handshake, Finished (20):
  • SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
  • ALPN, server accepted to use h2
  • Server certificate:
  • subject: CN=mydomain
  • start date: May 8 18:35:15 2024 GMT
  • expire date: Aug 6 18:35:14 2024 GMT
  • subjectAltName: host “www.mydomain” matched cert’s “*.mydomain”
  • issuer: C=US; O=Google Trust Services LLC; CN=GTS CA 1P5
  • SSL certificate verify ok.
  • Using HTTP2, server supports multiplexing
  • Connection state changed (HTTP/2 confirmed)
  • Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
  • TLSv1.2 (OUT), TLS header, Supplemental data (23):
  • TLSv1.2 (OUT), TLS header, Supplemental data (23):
  • TLSv1.2 (OUT), TLS header, Supplemental data (23):
  • Using Stream ID: 1 (easy handle 0x62525b0b6eb0)
  • TLSv1.2 (OUT), TLS header, Supplemental data (23):

Host: www.mydomain
user-agent: curl/7.81.0
accept: /

  • TLSv1.2 (IN), TLS header, Supplemental data (23):
  • TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
  • TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
  • old SSL session ID is stale, removing
  • TLSv1.2 (IN), TLS header, Supplemental data (23):
  • TLSv1.2 (OUT), TLS header, Supplemental data (23):
  • TLSv1.2 (IN), TLS header, Supplemental data (23):
  • TLSv1.2 (IN), TLS header, Supplemental data (23):
    < HTTP/2 522
    < date: Wed, 15 May 2024 19:38:40 GMT
    < content-type: text/plain; charset=UTF-8
    < content-length: 15
    < report-to: {“endpoints”:[{“url”:“”}],“group”:“cf-nel”,“max_age”:604800}
    < nel: {“success_fraction”:0,“report_to”:“cf-nel”,“max_age”:604800}
    < x-frame-options: SAMEORIGIN
    < referrer-policy: same-origin
    < cache-control: private, max-age=0, no-store, no-cache, must-revalidate, post-check=0, pre-check=0
    < expires: Thu, 01 Jan 1970 00:00:01 GMT
    < server: cloudflare
    < cf-ray: 884595ff3932284c-SEA
    < alt-svc: h3=“:443”; ma=86400
  • TLSv1.2 (IN), TLS header, Supplemental data (23):
  • TLSv1.2 (IN), TLS header, Supplemental data (23):
  • Connection #0 to host www.mydomain left intact

Welcome to the Cloudflare Community :logodrop:

When obfuscating domain names, please do not use real domain names that are not yours. There are reserved names such as that exist for that purpose. See RFC 2606 for more details. Know that it also can make assistance more difficult when you hide your domain name.

That question cannot be answered without knowing the FQDNs involved.

That has left you with an insecure site at the very least. You must use either a free automated CA, like Let’s Encrypt, a commercial certificate, or a free Cloudflare Origin CA certificate to secure your origin server. Many people think Cloudflare is magic, but that doesn’t change the laws of physics, nor can it secure the vulnerable traffic that you are sending between Cloudflare and your VPS in the clear.

It may interest you to know that when you have both A and AAAA records in your Cloudflare DNS, traffic from Cloudflare to your origin server will be sent over IPv4.

If you are not using the Cloudflare Docs as an active reference, I highly recommend it. It is by far one of the easiest ways to learn about Cloudflare functions and settings.

Appreciate the reply. The actual domain is ‘’ if that helps any. New forum users are limited to 4 URLs in a post so I had to obfuscate the domain in my original post above to hopefully explain what I was seeing in enough detail to try to paint the picture.

FWIW - yes I did consult the docs but to me they are are a bit too buzzwordy and cryptic but I wasn’t able to find this very simple use case documented in a layman’s terms howto here or anywhere else. So I figured try the forums since that’s part of what they’re there for.

The Cloudflare forums/wiki/whatever also is a bit of a maze for new users. I assume (assume) that when I switched providers to Cloudflare that they created the free Origin CA but I can’t even find that in the maze of the admin web pages. I can check whatever is needed given some ‘go here’ guidance. TFM isn’t helping there.

Anyway - agree that the goal should be SSL-only but I have not been able to find a combination of Cloudflare settings that works. Before my domain transferred, my domain worked just fine with SSL from LetsEncrypt, FWIW.

I’m ok with AAAA into CF going to ipv4 on the webserver side. AWS Lightsail supports either, but I can turn delete the AAAA records in DNS if that’ll help.

Also - I do limit web traffic so it comes from only US/CA/AU geoip domains so you’d have to be in one of those geoip regions. Yes I know that’s an imprecise science but it does quiet down a huge number of bots etc. from the usual suspect countries. Hopefully you’re in one of those geoip regions. I can disable that too (temporarily) if that’ll help resolve the issues…

I’d be thrilled to once again go SSL-only with working and (stretch goal) pointing to

Thanks again.

That will break Let’s Encrypt certificate issuance. They use multi-perspective validation and it will originate in countries outside of your restrictions. They are not the only automated CA using multi-perspective validation.

One Cloudflare setting that has interfered with HTTP-01 challenges for me is the Always Use TLS setting. I turn this off in Cloudflare and either create my own Cloudflare rule that exempts the /.well-known/acme-challenge path from redirection (and other settings, such as bot challenges, etc) or handle HTTPS redirection at the origin. Note that such redirection at the origin will break any site that uses Flexible, which is another reason to avoid that horrible and deceptive setting.

When you encounter that 522 response on your www hostnames, do you see the requests reach your server?

Hmmmm - looks relatively new. Sigh.

Again, the goal is to enable http/443 only on the webserver side, as you suggested as well. I would very much like to still be able to geoip block the usual offending countries, but if I sit behind a CF proxy then the originating ip isn’t visible to the nginx side, all that sees is CF ip which I specifically permitted in.

No - I do not see anything in the logs on the nginx side. My confusion is why does this happen for 'only the www alias ? (actually an A records, but the CNAME way fails too the same way)

You will be happier if you start restoring original visitor IPs. :grin:

Do you have a virtual host configured for that hostname? If you don’t see connection attempt in even an nginx error log, you may need to monitor your firewall when you make the connection attempts.

It is unlikely to be something that can be diagnosed from anywhere other than local to the nginx hot.

I might add that I can turn off the geoip block (in CF) and reenable the LetsEncrypt stuff (in nginx) if that would help debug. Feel free to IM me rather than go back and forth here if that helps. I’d be more than willing to post the missing howto if I can get it all working again.

Keeping the conversation on the forums is best, since you won’t want to see the bill that accompanies private correspondence. :wink:

It also means that someone else can jump in and help you when I inevitably have to put in work of my own and am unable to reply.

I think I got it. Only the www alias failed. The problem was a typo in the A record address. It was DNS. It is always DNS. Sigh. Shoulda done CNAME(s) rather than A records.

Thanks much for your time !

FWIW for future victims - I did the following:

  • renamed /etc/letsencrypt on the AWS host to move the old stuff out of the way just in case
  • reset the nginx config file to the default settings
  • (re) installed certbot on the host following the instructions (HERE) to not use snap for certbot.
  • ensured the /usr/bin/certbot symlink pointed to the correct location
  • created a new set of certs with all the names specified
  • and tested each of the three names via https which worked. Whew.

Then I manually added a cron job for renewals per the certbot docs (LINK)

SLEEPTIME=$(awk ‘BEGIN{srand(); print int(rand()*(3600+1))}’); echo “0 0,12 * * * root sleep $SLEEPTIME && certbot renew -q” | sudo tee -a /etc/crontab > /dev/null

1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.