Reverse proxy https report Error x509: certificate signed by unknown authority

1. Caddy version:

$ caddy version
v2.6.2 h1:wKoFIxpmOJLGl3QXoo6PNbYvGW4xLEgo32GPBEjWL8o=

2. How I installed, and run Caddy:

a. System environment:

$ cat /etc/centos-release
CentOS Linux release 7.9.2009 (Core)

b. Command:

$ caddy run --environ --config /etc/caddy/Caddyfil

c. Service/unit/compose file:

[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target

[Service]
Type=notify
User=proxy
Group=proxy
ExecStart=/usr/local/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/local/bin/caddy reload --config /etc/caddy/Caddyfile --force
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

d. My complete Caddy config:

{
	servers {
		protocols h1 h2 h3
	}
	log {
		output file /var/log/caddy/caddy.log
		level INFO
	}
}
my.smartpns.one {
	tls /etc/caddy/pns.crt /etc/caddy/pns.key
	reverse_proxy https://test.smartpns.one {
		#transport http {
		#	tls
		#	tls_insecure_skip_verify
		#	read_buffer 8192
		#}
		header_up Host {upstream_hostport}
		header_up X-Real-IP {remote}
		header_up X-Forwarded-For {remote}
		header_up X-Forwarded-Proto {scheme}
	}
	header /* {
		-Server
	}
	log {
		output file /var/log/caddy/http.log {
			roll_local_time
		}
		level INFO
		format console {
			time_format rfc3339
			time_local
		}
	}
}

3. The problem I’m having:

C:\Users\Administrator>curl -vL https://my.smartpns.one
*   Trying 219.139.73.98:443...
* Connected to my.smartpns.one (219.139.73.98) port 443 (#0)
* schannel: disabled automatic use of client certificate
* ALPN: offers http/1.1
* ALPN: server accepted http/1.1
> GET / HTTP/1.1
> Host: my.smartpns.one
> User-Agent: curl/7.83.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 502 Bad Gateway
< Alt-Svc: h3=":443"; ma=2592000
< Server: Caddy
< Date: Tue, 24 Jan 2023 08:12:10 GMT
< Content-Length: 0
<
* Connection #0 to host my.smartpns.pne left intact

4. Error messages and/or full log output:

$ tail -f /var/log/caddy/caddy.log 
{"level":"info","ts":1674547860.5913746,"logger":"tls","msg":"cleaning storage unit","description":"FileStorage:/home/proxy/.local/share/caddy"}
{"level":"info","ts":1674547860.5914052,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
{"level":"info","ts":1674547860.5919294,"logger":"tls","msg":"finished cleaning storage units"}
{"level":"info","ts":1674547860.59198,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
{"level":"info","ts":1674547860.592036,"logger":"http.log","msg":"server running","name":"srv1","protocols":["h1","h2","h3"]}
{"level":"info","ts":1674547860.5920794,"logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2","h3"]}
{"level":"info","ts":1674547860.592302,"msg":"autosaved config (load with --resume flag)","file":"/home/proxy/.config/caddy/autosave.json"}
{"level":"info","ts":1674547860.5923667,"msg":"serving initial configuration"}
{"level":"error","ts":1674547925.3170397,"logger":"http.log.error.log1","msg":"x509: certificate signed by unknown authority","request":{"remote_ip":"20.43.84.40","remote_port":"31056","proto":"HTTP/1.1","method":"GET","host":"my.smartpns.one","uri":"/","headers":{"User-Agent":["curl/7.83.1"],"Accept":["*/*"]},"tls":{"resumed":false,"version":771,"cipher_suite":49199,"proto":"http/1.1","server_name":"my.smartpns.one"}},"duration":0.003351671,"status":502,"err_id":"9i70z92fz","err_trace":"reverseproxy.statusError (reverseproxy.go:1272)"}

5. What I already tried:

I tried to use the configuration:

transport http {
	tls
	tls_insecure_skip_verify
	read_buffer 8192
}

But when I visit the site, I get this error:

Client sent an HTTP request to an HTTPS server.

You don’t need these lines. Remove them.

There’s no benefit to removing the Server header. You can remove this.

That’s already the default, so there’s no need to specify this.

What kind of certificate is that server using?

If it’s not a publicly trusted cert, then the correct way to establish trust is to either add the cert that signed the upstream’s cert to your system’s trust store, or use the tls_trusted_ca_certs option of the http transport to trust it.

Are you sure that’s not a viable option?

Thanks, I will remove the unwanted lines.

The upstream nginx server uses the exact same cert as this server. Certificate info:

$ openssl x509 -in /etc/caddy/pns.crt -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            61:2a:20:dc:9c:cd:af:91:57:ab:7b:aa:ff:ca:e9:ed
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=GB, ST=Greater Manchester, L=Salford, O=Sectigo Limited, CN=Sectigo RSA Domain Validation Secure Server CA
        Validity
            Not Before: Jan  5 00:00:00 2022 GMT
            Not After : Feb  5 23:59:59 2023 GMT
        Subject: CN=*.smartpns.one
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
......

I tried to use http transport option to make caddy trust the certificate. But this will create a new problem, when I view this site using my browser, it will jump just like the url of http://my.smartpns.one:443. I get this error:

Client sent an HTTP request to an HTTPS server.

Then your upstream is misconfigured. It should not perform a redirect to HTTP.

That’s not a problem with Caddy, it’s a problem with your upstream server or app.

OK, thanks. Can I set the CA file for PKI options in the global options to make caddy trust this certificate. Maybe if so there is no need to set the http transport.

There’s no global options for proxy transports. You need to configure it per proxy if you have more than one. You can use Caddyfile snippets to avoid repeating config Caddyfile Concepts — Caddy Documentation