Using Both Cloudflare Origin Certificate and Lets encrypt

1. The problem I’m having:

I wish to transition from Nginx Proxy Manager over to caddy, but I seem to have an issue with using both cf origin certs (cf proxy) and let’s encrypt certs (just dns). If I pick just let’s encrypt works fine, if I pick cf it works fine, it’s just using both that has an issue.

2. Error messages and/or full log output:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

3. Caddy version:

v2.8.4 h1:q3pe0wpBj1OcHFZ3n/1nl4V4bxBrYoSoab7rL9BMYNk=

4. How I installed and ran Caddy:

a. System environment:

Debian 6.1.99-1 (2024-07-15) x86_64 GNU/Linux
Caddy is running inside a docker container

b. Command:

docker compose up -d

c. Service/unit/compose file:

services:
  caddy:
    container_name: caddy
    image: caddy:latest
    cap_add:
      - NET_ADMIN
    ports:
      - "50226:80"
      - "60204:443"
      - "60204:443/udp"
    volumes:
      - '${HOME}/docker-data/caddy/Caddyfile:/etc/caddy/Caddyfile'
      - '${HOME}/docker-data/caddy/site:/srv'
      - '${HOME}/docker-data/caddy/data:/data'
      - '${HOME}/docker-data/caddy/caddy_config:/config'
      - '${HOME}/docker-data/caddy/certs:/certs'
    restart: unless-stopped

networks:
  default:
    name: caddy
    external: true

d. My complete Caddy config:

books.xincept.xyz {
    reverse_proxy 172.18.0.1:50224
}
air.xincept.xyz {
    reverse_proxy 172.18.0.1:50212
    tls /certs/xincept.xyz.pem /certs/xincept.xyz.key
}
workspace.xincept.xyz {
    reverse_proxy 172.18.0.1:3010
    tls /certs/xincept.xyz.pem /certs/xincept.xyz.key
}

5. Links to relevant resources:

I had asked about this a few years ago and was wondering if there was an update on this? Or how would i be able to do this with json i tried myself for a few hours and gave up, i tried using gpt and got a semi working config that only worked when i added to json file but then logs were getting spammed by lets encrypt trying to get certs for subdomains using cf origin cert. But they were showing up as lets encrypt and cf but then i wasnt able to acess it from my lan.

"automatic_https": {
  "ignore_loaded_certificates": true
}

I also stumbled upon this and was wondering if it was also a potential solution?

And here are logs:

{"level":"info","ts":1728853115.0118105,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
{"level":"info","ts":1728853115.014349,"msg":"adapted config to JSON","adapter":"caddyfile"}
{"level":"warn","ts":1728853115.0143595,"msg":"Caddyfile input is not formatted; run 'caddy fmt --overwrite' to fix inconsistencies","adapter":"caddyfile","file":"/etc/caddy/Caddyfile","line":2}
{"level":"info","ts":1728853115.0152671,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]}
{"level":"info","ts":1728853115.0162508,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc000495c80"}
{"level":"warn","ts":1728853115.016788,"logger":"tls","msg":"stapling OCSP","error":"no OCSP stapling for [cloudflare origin certificate *.xincept.xyz xincept.xyz]: no URL to issuing certificate"}
{"level":"info","ts":1728853115.0168664,"logger":"http.auto_https","msg":"skipping automatic certificate management because one or more matching certificates are already loaded","domain":"air.xincept.xyz","server_name":"srv0"}
{"level":"info","ts":1728853115.016874,"logger":"http.auto_https","msg":"skipping automatic certificate management because one or more matching certificates are already loaded","domain":"workspace.xincept.xyz","server_name":"srv0"}
{"level":"info","ts":1728853115.016878,"logger":"http.auto_https","msg":"skipping automatic certificate management because one or more matching certificates are already loaded","domain":"books.xincept.xyz","server_name":"srv0"}
{"level":"info","ts":1728853115.0168808,"logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
{"level":"info","ts":1728853115.019041,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
{"level":"info","ts":1728853115.020389,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
{"level":"info","ts":1728853115.0204937,"logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2","h3"]}
{"level":"info","ts":1728853115.0210574,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
{"level":"info","ts":1728853115.0210874,"msg":"serving initial configuration"}
{"level":"info","ts":1728853115.024382,"logger":"tls","msg":"storage cleaning happened too recently; skipping for now","storage":"FileStorage:/data/caddy","instance":"909323ff-c7fe-438d-bdba-427a3e9cea1b","try_again":1728939515.0243807,"try_again_in":86399.999999683}
{"level":"info","ts":1728853115.0244448,"logger":"tls","msg":"finished cleaning storage units"}

I don’t think prefer_wildcard will work for your case because you’re not actually using a wildcard site block in your config. It’s moreso to make it easier to write a config where Caddy manages a wildcard cert, skipping issuance of individual certs for subdomains.

Your case is the opposite though. The reason origin certs mess things up is because the origin certs contain wilcard SANs, so once Caddy loads it into its cert cache, it “covers” the other subdomains you have in your config and Caddy thinks “oh I don’t need to manage certs for the rest then”.

I’ve been thinking to add a tls force_automate option (similar to tls internal in terms of how it looks in the config) which would tell Caddy “always manage a cert for the domains in this site” which would make sure a managed cert would be in the cache which would take precedence over the origin cert. It would mean every site which shouldn’t use the origin cert would need tls force_automate set.

I haven’t finished the implementation for that yet, the TLS config surface in the Caddyfile is really complicated unfortunately (so many edgecases to handle) and writing tests for it is very difficult (we don’t have the infrastructure to test the config side effects yet).

It is possible to do this with JSON config already, yes. You would need to configure the tls app with an automation policy that lists the domains you don’t want to use the origin cert with.

1 Like

Thank you for the quick reply!

I tried giving it another go, and I keep having Origin cert for all three subdomains instead of just the two, I had gpt try to help as well, but I just kept getting more errors. Do you know what I’m missing? for the books subdomain i get a “This connection is not private” when I view the certificate it says Cloudflare origin cert I have it as just DNS (grey cloud) on cf dashboard.

caddy.json

{
    "apps": {
        "http": {
            "servers": {
                "srv0": {
                    "listen": [":80", ":443"],
                    "routes": [
                        {
                            "match": [
                                {
                                    "host": ["books.xincept.xyz"]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "reverse_proxy",
                                    "upstreams": [
                                        {
                                            "dial": "172.18.0.1:50224"
                                        }
                                    ]
                                }
                            ],
                            "terminal": true
                        },
                        {
                            "match": [
                                {
                                    "host": ["air.xincept.xyz"]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "reverse_proxy",
                                    "upstreams": [
                                        {
                                            "dial": "172.18.0.1:50212"
                                        }
                                    ]
                                }
                            ],
                            "terminal": true
                        },
                        {
                            "match": [
                                {
                                    "host": ["workspace.xincept.xyz"]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "reverse_proxy",
                                    "upstreams": [
                                        {
                                            "dial": "172.18.0.1:3010"
                                        }
                                    ]
                                }
                            ],
                            "terminal": true
                        }
                    ],
                    "tls_connection_policies": [
                        {
                            "match": {
                                "sni": ["air.xincept.xyz", "workspace.xincept.xyz"]
                            },
                            "certificate_selection": {
                                "any_tag": ["cert0"]
                            }
                        },
                        {}
                    ]
                }
            }
        },
        "tls": {
            "certificates": {
                "load_files": [
                    {
                        "certificate": "/certs/xincept.xyz.pem",
                        "key": "/certs/xincept.xyz.key",
                        "tags": ["cert0"]
                    }
                ]
            },
            "automation": {
                "policies": [
                    {
                        "subjects": ["books.xincept.xyz"],
                        "issuers": [
                            {
                                "module": "acme",
                                "ca": "https://acme-v02.api.letsencrypt.org/directory"
                            }
                        ]
                    }
                ]
            }
        }
    }
}

logs

{"level":"info","ts":1728966159.8609538,"msg":"using config from file","file":"/etc/caddy/caddy.json"}
{"level":"info","ts":1728966159.861926,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//127.0.0.1:2019","//localhost:2019","//[::1]:2019"]}
{"level":"info","ts":1728966159.8621464,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc000588c00"}
{"level":"warn","ts":1728966159.8624153,"logger":"tls","msg":"stapling OCSP","error":"no OCSP stapling for [cloudflare origin certificate *.xincept.xyz xincept.xyz]: no URL to issuing certificate"}
{"level":"info","ts":1728966159.8626695,"logger":"http.auto_https","msg":"skipping automatic certificate management because one or more matching certificates are already loaded","domain":"books.xincept.xyz","server_name":"srv0"}
{"level":"info","ts":1728966159.8626788,"logger":"http.auto_https","msg":"skipping automatic certificate management because one or more matching certificates are already loaded","domain":"air.xincept.xyz","server_name":"srv0"}
{"level":"info","ts":1728966159.8626833,"logger":"http.auto_https","msg":"skipping automatic certificate management because one or more matching certificates are already loaded","domain":"workspace.xincept.xyz","server_name":"srv0"}
{"level":"info","ts":1728966159.8626862,"logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
{"level":"info","ts":1728966159.8631506,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
{"level":"info","ts":1728966159.8633864,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
{"level":"info","ts":1728966159.8635445,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
{"level":"info","ts":1728966159.863599,"msg":"serving initial configuration"}
{"level":"info","ts":1728966159.8652592,"logger":"tls","msg":"storage cleaning happened too recently; skipping for now","storage":"FileStorage:/data/caddy","instance":"909323ff-c7fe-438d-bdba-427a3e9cea1b","try_again":1729052559.8652582,"try_again_in":86399.999999684}
{"level":"info","ts":1728966159.8653224,"logger":"tls","msg":"finished cleaning storage units"}

Now im able to at least have the page load Im getting “Your connection is not private” but after doing advance and proceed I get the site loading, but certificate is still Cloudflare Origin Cert. I tired only doing the lets encrypt domain with nothing else and that worked so now I have a lets encrypt cert for that but the moment I add Origin sub domains again im back at square one. Not sure what im doing wrong.

here is current caddy.json

{
    "apps": {
        "http": {
            "servers": {
                "srv0": {
                    "listen": [":443"],
                    "routes": [
                        {
                            "match": [
                                {
                                    "host": ["books.xincept.xyz"]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "reverse_proxy",
                                    "upstreams": [
                                        {
                                            "dial": "172.18.0.1:50224"
                                        }
                                    ]
                                }
                            ],
                            "terminal": true
                        },
                        {
                            "match": [
                                {
                                    "host": ["air.xincept.xyz"]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "reverse_proxy",
                                    "upstreams": [
                                        {
                                            "dial": "172.18.0.1:50212"
                                        }
                                    ]
                                }
                            ],
                            "terminal": true
                        },
                        {
                            "match": [
                                {
                                    "host": ["workspace.xincept.xyz"]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "reverse_proxy",
                                    "upstreams": [
                                        {
                                            "dial": "172.18.0.1:3010"
                                        }
                                    ]
                                }
                            ],
                            "terminal": true
                        }
                    ],
                    "tls_connection_policies": [
                        {
                            "match": {
                                "sni": ["air.xincept.xyz", "workspace.xincept.xyz"]
                            },
                            "certificate_selection": {
                                "any_tag": ["cert0"]
                            }
                        },
                        {
                            "match": {
                                "sni": ["books.xincept.xyz"]
                            }
                        }
                    ]
                }
            }
        },
        "tls": {
            "certificates": {
                "load_files": [
                    {
                        "certificate": "/certs/xincept.xyz.pem",
                        "key": "/certs/xincept.xyz.key",
                        "tags": ["cert0"]
                    }
                ]
            },
            "automation": {
                "policies": [
                    {
                        "subjects": ["books.xincept.xyz"],
                        "issuers": [
                            {
                                "module": "acme",
                                "ca": "https://acme-v02.api.letsencrypt.org/directory"
                            }
                        ]
                    },
                    {
                        "subjects": ["air.xincept.xyz", "workspace.xincept.xyz"],
                        "issuers": []
                    }
                ]
            }
        }
    }
}

logs

{"level":"info","ts":1729022045.287328,"msg":"using config from file","file":"/etc/caddy/caddy.json"}
{"level":"info","ts":1729022045.2893322,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]}
{"level":"info","ts":1729022045.2899382,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc00049fc80"}
{"level":"warn","ts":1729022045.2905986,"logger":"tls","msg":"stapling OCSP","error":"no OCSP stapling for [cloudflare origin certificate *.xincept.xyz xincept.xyz]: no URL to issuing certificate"}
{"level":"info","ts":1729022045.2906742,"logger":"http.auto_https","msg":"skipping automatic certificate management because one or more matching certificates are already loaded","domain":"air.xincept.xyz","server_name":"srv0"}
{"level":"info","ts":1729022045.290684,"logger":"http.auto_https","msg":"skipping automatic certificate management because one or more matching certificates are already loaded","domain":"workspace.xincept.xyz","server_name":"srv0"}
{"level":"info","ts":1729022045.2906907,"logger":"http.auto_https","msg":"skipping automatic certificate management because one or more matching certificates are already loaded","domain":"books.xincept.xyz","server_name":"srv0"}
{"level":"info","ts":1729022045.2906966,"logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
{"level":"info","ts":1729022045.2918265,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
{"level":"info","ts":1729022045.2921062,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
{"level":"info","ts":1729022045.2921975,"logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2","h3"]}
{"level":"info","ts":1729022045.2923737,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
{"level":"info","ts":1729022045.2923863,"msg":"serving initial configuration"}
{"level":"info","ts":1729022045.2946074,"logger":"tls","msg":"storage cleaning happened too recently; skipping for now","storage":"FileStorage:/data/caddy","instance":"909323ff-c7fe-438d-bdba-427a3e9cea1b","try_again":1729108445.2946057,"try_again_in":86399.99999957}
{"level":"info","ts":1729022045.2947567,"logger":"tls","msg":"finished cleaning storage units"}

Got it working! started from scratch converting json from Caddyfile and working my way from there. Not sure if this is the best way to do it or not, but it works. Please let me know if there is a better way / anything you would change.

{
  "apps": {
    "http": {
      "servers": {
        "srv0": {
          "listen": [":443"],
          "routes": [
            {
              "match": [
                {
                  "host": ["workspace.xincept.xyz"]
                }
              ],
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [
                            {
                              "dial": "172.18.0.1:3010"
                            }
                          ]
                        }
                      ]
                    }
                  ]
                }
              ],
              "terminal": true
            },
            {
              "match": [
                {
                  "host": ["books.xincept.xyz"]
                }
              ],
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [
                            {
                              "dial": "172.18.0.1:50224"
                            }
                          ]
                        }
                      ]
                    }
                  ]
                }
              ],
              "terminal": true
            },
            {
              "match": [
                {
                  "host": ["air.xincept.xyz"]
                }
              ],
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [
                            {
                              "dial": "172.18.0.1:50212"
                            }
                          ]
                        }
                      ]
                    }
                  ]
                }
              ],
              "terminal": true
            }
          ],
          "tls_connection_policies": [
            {
              "match": {
                "sni": ["workspace.xincept.xyz"]
              },
              "certificate_selection": {
                "any_tag": ["cert0"]
              }
            },
            {
              "match": {
                "sni": ["air.xincept.xyz"]
              },
              "certificate_selection": {
                "any_tag": ["cert0"]
              }
            },
            {}
          ],
          "automatic_https": {
            "ignore_loaded_certificates": true,
	    "skip_certificates": ["workspace.xincept.xyz", "air.xincept.xyz"]
          }
        }
      }
    },
    "tls": {
      "certificates": {
        "load_files": [
          {
            "certificate": "/certs/xincept.xyz.pem",
            "key": "/certs/xincept.xyz.key",
            "tags": [
              "cert0"
            ]
          }
        ]
      },
      "automation": {
	"policies": [
	  {
	    "subjects": ["books.xincept.xyz"],
	    "issuers": [
	      {
		"module": "acme",
		"ca": "https://acme-v02.api.letsencrypt.org/directory"
	      }
	    ]
	  }
	]
      }
    }
  }
}

logs

{"level":"info","ts":1729055936.0640512,"msg":"using config from file","file":"/etc/caddy/caddy.json"}
{"level":"info","ts":1729055936.065546,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]}
{"level":"info","ts":1729055936.0660672,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc000710480"}
{"level":"warn","ts":1729055936.066854,"logger":"tls","msg":"stapling OCSP","error":"no OCSP stapling for [cloudflare origin certificate *.xincept.xyz xincept.xyz]: no URL to issuing certificate"}
{"level":"info","ts":1729055936.0674977,"logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
{"level":"info","ts":1729055936.0680542,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
{"level":"info","ts":1729055936.0682201,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
{"level":"info","ts":1729055936.0682592,"logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2","h3"]}
{"level":"info","ts":1729055936.0682673,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["books.xincept.xyz"]}
{"level":"info","ts":1729055936.069549,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
{"level":"info","ts":1729055936.0695574,"msg":"serving initial configuration"}
{"level":"info","ts":1729055936.0703018,"logger":"tls","msg":"storage cleaning happened too recently; skipping for now","storage":"FileStorage:/data/caddy","instance":"909323ff-c7fe-438d-bdba-427a3e9cea1b","try_again":1729142336.0703,"try_again_in":86399.999999636}
{"level":"info","ts":1729055936.0703957,"logger":"tls","msg":"finished cleaning storage units"}
1 Like

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