SSL/TLS in 2026: What Solo Builders Get Wrong
Cloudflare sits in front of your site, the browser shows a padlock, and you assume your traffic is encrypted. For a lot of solo builders running self-hosted infrastructure, that assumption is wrong. The padlock means your visitor's connection to Cloudflare is encrypted. It says nothing about what happens between Cloudflare and your server.
That gap is where the problem lives.
The Setting That Matters Most
Cloudflare's SSL/TLS configuration has four modes: Off, Flexible, Full, and Full (Strict). The names sound like a gradient from less secure to more secure, and they are, but the gap between Flexible and Full is not incremental. It is a fundamentally different security posture.
Flexible encrypts traffic between the visitor and Cloudflare. Traffic between Cloudflare and your origin server travels over plain HTTP. Your data crosses the open internet unencrypted on the leg you control the least. Login credentials, API keys, form submissions, session tokens. All in cleartext between Cloudflare's edge and your box.
Full encrypts both legs, but accepts any certificate on your origin, including self-signed and expired ones. This is better than Flexible by a wide margin. The traffic is encrypted in transit, which defeats passive eavesdropping. But it does not verify that Cloudflare is actually talking to your server and not something sitting between them.
Full (Strict) encrypts both legs and validates the origin certificate against a trusted CA. This is the setting you want. Cloudflare verifies it is talking to the server you intend, with a certificate that has not expired and was issued by a recognized authority. This is actual end-to-end encryption with authentication.
The default for many Cloudflare setups is Flexible. If you pointed your domain at Cloudflare and never touched the SSL setting, your origin traffic is unencrypted right now. The padlock in your visitor's browser will not tell them that.
Why Flexible Persists
Flexible exists because it is the path of least resistance. You sign up for Cloudflare, point your DNS, and everything works. No certificate to install on your server, no configuration to debug, no renewal to manage. The visitor sees HTTPS and a padlock. From the outside, it looks correct.
Solo builders hit this trap more than teams because there is no separate infrastructure person asking questions. You set up Cloudflare to get DDoS protection and caching, the site loaded over HTTPS, and you moved on to the next thing. The SSL settings page in the Cloudflare dashboard is not where you spend your time. Months later, you have a production service handling real user data over a connection that is only half-encrypted.
This is not a theoretical concern. HTTP traffic between Cloudflare and your origin traverses the public internet. Anyone on the network path between Cloudflare's edge node and your server can read it. If your origin is a Mac Mini on a residential connection, that path includes your ISP's entire network. If it is a VPS, that path includes the hosting provider's internal network. The attack surface is real.
Fixing It with Let's Encrypt
The standard fix is a real TLS certificate on your origin server. Let's Encrypt issues them for free, and the tooling in 2026 makes this close to zero-effort if you pick the right server.
Caddy is the fastest path. It handles certificate issuance, renewal, and HTTPS configuration automatically. Point Caddy at your domain, and it obtains a Let's Encrypt certificate, configures TLS, and renews the certificate before it expires. No cron jobs, no manual renewal commands, no certificate files to manage.
# Caddyfile — this is the entire configuration
yourdomain.com {
reverse_proxy localhost:3000
}
That is not a simplified example. That is the actual configuration. Caddy sees the domain name, requests a certificate from Let's Encrypt via the ACME protocol, and serves your application over TLS. Renewal happens in the background, roughly 30 days before expiration.
If you are already running Nginx or Apache and do not want to switch, certbot handles Let's Encrypt certificates as a standalone tool.
sudo certbot --nginx -d yourdomain.com
# or
sudo certbot --apache -d yourdomain.com
Certbot modifies your existing server configuration to use the new certificate and sets up a systemd timer for automatic renewal. It works, but it is more moving parts than Caddy. You are managing the certificate lifecycle alongside your web server configuration instead of having one tool handle both.
Once your origin has a valid certificate, change the Cloudflare SSL setting to Full (Strict). Both legs are now encrypted, and Cloudflare validates your origin's identity on every request.
Cloudflare Origin Certificates
There is a middle path that some solo builders prefer: Cloudflare Origin Certificates. These are certificates issued by Cloudflare specifically for the connection between their edge and your server. They are free, last up to 15 years, and require zero renewal management.
The tradeoff is that they are only trusted by Cloudflare. If you ever need to bypass Cloudflare and point traffic directly at your origin, those certificates will throw browser errors because no public CA has vouched for them. For a service that will always sit behind Cloudflare, this is a reasonable choice. For anything where you might need direct origin access during debugging or failover, a Let's Encrypt certificate is more flexible.
To use them: go to the SSL/TLS section of your Cloudflare dashboard, select Origin Server, and generate a certificate. Install it on your server, set the SSL mode to Full (Strict), and the connection is encrypted and authenticated in both directions.
mTLS: The Step Most People Skip
Standard TLS is one-directional authentication. Your origin proves its identity to Cloudflare. But Cloudflare does not prove its identity to your origin. Any client that connects to your server's port 443 with a valid-looking request gets through. Your origin has no way to verify that the incoming request actually came from Cloudflare.
Mutual TLS (mTLS) closes that gap. Both sides present certificates. Cloudflare proves it is Cloudflare, and your origin proves it is your origin. Any connection that does not present the correct client certificate gets rejected at the TLS handshake level, before your application even sees the request.
For solo builders, this matters because of a specific attack pattern: origin IP discovery. If someone discovers your server's actual IP address, they can bypass Cloudflare entirely and hit your origin directly. Without mTLS, your server will happily respond to those requests. With mTLS, connections without Cloudflare's client certificate are refused.
Cloudflare calls this feature Authenticated Origin Pulls. Enabling it requires downloading Cloudflare's client certificate and configuring your web server to require it.
# Nginx configuration for mTLS with Cloudflare
ssl_client_certificate /etc/nginx/certs/cloudflare-origin-pull.pem;
ssl_verify_client on;
# Caddy configuration for mTLS
yourdomain.com {
tls {
client_auth {
mode require_and_verify
trusted_ca_cert_file /etc/caddy/cloudflare-origin-pull.pem
}
}
reverse_proxy localhost:3000
}
After enabling this, requests that do not present Cloudflare's client certificate receive a 403 or a TLS handshake failure. Your origin only speaks to Cloudflare, and Cloudflare only speaks to your verified origin. The connection is encrypted, authenticated, and locked to the specific parties you intend.
The Audit Takes Five Minutes
If you are running anything behind Cloudflare, the check is straightforward. Log into the Cloudflare dashboard, go to SSL/TLS, and look at the mode. If it says Flexible, your origin traffic is unencrypted. If it says Full without Strict, your origin traffic is encrypted but unauthenticated. Either one needs to change.
The fix depends on how much you want to invest:
- Minimum viable: Generate a Cloudflare Origin Certificate, install it, set mode to Full (Strict). Fifteen minutes, no renewals for 15 years.
- Standard: Install Caddy or certbot for a Let's Encrypt certificate, set mode to Full (Strict). Twenty minutes, automatic renewals.
- Proper: Either of the above plus Authenticated Origin Pulls for mTLS. Thirty minutes total, and your origin only accepts traffic from Cloudflare.
There is no good reason to stay on Flexible. The padlock in your visitor's browser is a promise, and on Flexible, you are breaking half of it. The tooling to fix it is free, the configuration is minimal, and the difference between "looks encrypted" and "is encrypted" is the difference between a security posture and a security theater.
Your visitors trust the padlock. Make sure you deserve it.