Defining own CA using the PKI module fails with "no such file or directory"

1. Caddy version (caddy version):

./caddy version
v2.4.6 h1:HGkGICFGvyrodcqOOclHKfvJC0qTU7vny/7FhYp9hNw=

2. How I run Caddy:

I am trying something out and run caddy as non root user on the command line as for my test I don’t need higher privileges.

a. System environment:

Linux Mint 20.2

b. Command:

$ pwd
/tmp/tmp.DeLqOfdK5w
$ ./caddy run

c. Service/unit/compose file:

N/A

d. My complete Caddyfile or JSON config:

{
	"storage": {
		"module": "file_system",
		"root": "/tmp/tmp.DeLqOfdK5w"
	},
	"apps": {
		"pki": {
			"certificate_authorities": {
				"customca": {
					"name": "my custom CA name",
					"root_common_name": "custom CA - root",
					"intermediate_common_name": "custom CA - intermediate",
					"install_trust": false,
					"root": {},
					"intermediate": {}
				}
			}
		}
	}
}

3. The problem I’m having:

I am trying to get Caddy to create a local CA in my temporary directory so that I can later use it with more configuration to create certificates off of it.

When applying the configuration above, Caddy throws an unexpected error of “no such file or directory”.

4. Error messages and/or full log output:

When trying to set the configuration above I get this:

$ curl localhost:2019/load -X POST -H "Content-Type: application/json" -d @caddy.json
{"error":"loading config: loading new config: loading pki app module: provision pki: provisioning CA 'customca': open : no such file or directory"}
./caddy run
2021/12/02 21:23:41.766 INFO    admin   admin endpoint started  {"address": "tcp/localhost:2019", "enforce_origin": false, "origins": ["127.0.0.1:2019", "localhost:2019", "[::1]:2019"]}
2021/12/02 21:23:41.766 INFO    serving initial configuration
2021/12/02 21:23:52.969 INFO    admin.api       received request        {"method": "POST", "host": "localhost:2019", "uri": "/load", "remote_addr": "127.0.0.1:46260", "headers": {"Accept":["*/*"],"Content-Length":["368"],"Content-Type":["application/json"],"User-Agent":["curl/7.68.0"]}}
2021/12/02 21:23:52.969 INFO    admin   admin endpoint started  {"address": "tcp/localhost:2019", "enforce_origin": false, "origins": ["localhost:2019", "[::1]:2019", "127.0.0.1:2019"]}
2021/12/02 21:23:52.971 ERROR   admin.api       request error   {"error": "loading config: loading new config: loading pki app module: provision pki: provisioning CA 'customca': open : no such file or directory", "status_code": 400}
2021/12/02 21:23:52.974 INFO    admin   stopped previous server {"address": "tcp/localhost:2019"}

My thought was that Caddy would create the directories needed in the root dir.
Is this assumption correct? What do I have to do to to get the above working?

5. What I already tried:

I checked out the API documentation, searched the forum as well as GitHub issues for tickets or posts containing the phrase “certificate_authorities” to maybe find others with similar problems.

As I couldn’t find any, I’m posting here :man_shrugging:

The documentation at JSON Config Structure - Caddy Documentation states the following:

The root certificate to use; if null, one will be generated.

I am somewhat under the impression that the error and this is somewhat related but from the docs it isn’t clear.
I also am not a Go dev so I haven’t read the code (also I don’t think that reading the code would help me or is the way to go anyway).

6. Links to relevant resources:

Remove these lines, this is what’s triggering the error. These options are for specifying a path to a file that contains an existing root and intermediate cert. Setting them to {} is not correct.

Thank you! That worked exactly as you said.

The docs at https://caddyserver.com/docs/json/apps/pki/certificate_authorities/root/ say

The root certificate to use; if null, one will be generated.

So this is a bit confusing then, right?
I guess it makes sense eventually after the PKI module has created the files and structure, how would it know the parameters for these values? But still confusing.

One thing that I noticed just now as you solved my problem (thanks :slight_smile: !) I got prompted for my root pw:

./caddy run
2021/12/02 21:54:45.010 INFO    admin   admin endpoint started  {"address": "tcp/localhost:2019", "enforce_origin": false, "origins": ["localhost:2019", "[::1]:2019", "127.0.0.1:2019"]}
2021/12/02 21:54:45.010 INFO    serving initial configuration
2021/12/02 21:54:47.018 INFO    admin.api       received request        {"method": "POST", "host": "localhost:2019", "uri": "/load", "remote_addr": "127.0.0.1:46540", "headers": {"Accept":["*/*"],"Content-Length":["321"],"Content-Type":["application/json"],"User-Agent":["curl/7.68.0"]}}
2021/12/02 21:54:47.019 INFO    admin   admin endpoint started  {"address": "tcp/localhost:2019", "enforce_origin": false, "origins": ["localhost:2019", "[::1]:2019", "127.0.0.1:2019"]}
2021/12/02 21:54:47.021 WARN    pki.ca.customca root certificate trust store installation disabled; unconfigured clients may show warnings      {"path": "storage:pki/authorities/customca/root.crt"}
2021/12/02 21:54:47.034 WARN    pki.ca.local    installing root certificate (you might be prompted for password)        {"path": "storage:pki/authorities/local/root.crt"}
2021/12/02 22:54:47 certificate installed properly in NSS security databases
2021/12/02 22:54:47 define JAVA_HOME environment variable to use the Java trust
2021/12/02 22:54:48 certificate installed properly in linux trusts
2021/12/02 21:54:48.547 INFO    autosaved config (load with --resume flag)      {"file": "/home/moritz/.config/caddy/autosave.json"}
2021/12/02 21:54:48.547 INFO    admin.api       load complete
2021/12/02 21:54:48.612 INFO    admin   stopped previous server {"address": "tcp/localhost:2019"}

Even though I have set

"install_trust": false

Are there other flags which I need to set to false for this to not happen?

1 Like

Ahhh! I think I got it. I set "install_trust": false for my customca CA but not for the default one.

After adapting my config to this:

{
	"storage": {
		"module": "file_system",
		"root": "/tmp/tmp.DeLqOfdK5w"
	},
	"apps": {
		"pki": {
			"certificate_authorities": {
				"customca": {
					"name": "my custom CA name",
					"root_common_name": "custom CA - root",
					"intermediate_common_name": "custom CA - intermediate",
					"install_trust": false
				},
				"local": {
					"install_trust": false
				}
			}
		}
	}
}

it worked flawlessly.

1 Like

It’s accurate. You didn’t set it to null, you set it to an empty object. That’s not the same thing.

That’s because the local CA was also activated, but that one didn’t have install_trust set to false.

It depends what else you have in your config that might’ve activated that (you only shared a subset of your config I think – please post the whole thing, it’s relevant). But the default CA name is local.

You can configure the local CA to not install either, just add another item inside certificate_authorities for the local CA.

Oops I didn’t see the 2nd comment before writing – yep you got it!

:grinning_face_with_smiling_eyes:

2 Likes

I know where you’re getting at, but that isn’t what I was doing.
But I didn’t have to post more, as the configuration I shared in the initial post was actually the one I was using to figure out what the root cause was.
Knowing the problem was with the PKI module, it didn’t make sense to have my logging and TLS module stuff in there.
If the problem would’ve been in conjunction with another module, then sure I would’ve posted more.
:slight_smile:

I think I just got confused after reading this in the forum: PKI with default CAs not working
and wasn’t realizing that null is actually something else than an empty object. Thanks for clearing that up Francis :slight_smile:

1 Like

Hmm, strange. Not sure why it tried to set up the local CA then. It should only need to do that if something tries to use it.

It appears in the config, so that’s probably why.

It didn’t in the config in the first comment.

Francis is absolutely correct here, Matt.

See this screenshot:

What could be wrong here? What are we missing to explain this behavior?

1 Like

I’ll have to take a dive in the code to figure it out. I probably won’t have time to until sometime next week I think. Should be pretty easy to replicate.

1 Like

Alright, I did a bit of work this evening to fix this. Pretty simple.

2 Likes

I just built caddy from your branch and the fix solved the problem :slight_smile:


And to have it a bit more accessible to others:

./caddy run
2021/12/07 09:57:03.657 INFO    admin   admin endpoint started  {"address": "tcp/localhost:2019", "enforce_origin": false, "origins": ["localhost:2019", "[::1]:2019", "127.0.0.1:2019"]}
2021/12/07 09:57:03.657 INFO    serving initial configuration
2021/12/07 09:57:12.475 INFO    admin.api       received request        {"method": "POST", "host": "localhost:2019", "uri": "/load", "remote_ip": "127.0.0.1", "remote_port": "33324", "headers": {"Accept":["*/*"],"Content-Length":["341"],"Content-Type":["application/json"],"User-Agent":["curl/7.68.0"]}}
2021/12/07 09:57:12.477 INFO    admin   admin endpoint started  {"address": "tcp/localhost:2019", "enforce_origin": false, "origins": ["localhost:2019", "[::1]:2019", "127.0.0.1:2019"]}
2021/12/07 09:57:12.478 WARN    pki.ca.customca root certificate trust store installation disabled; unconfigured clients may show warnings      {"path": "storage:pki/authorities/customca/root.crt"}
2021/12/07 09:57:12.478 INFO    autosaved config (load with --resume flag)      {"file": "/home/moritz/.config/caddy/autosave.json"}
2021/12/07 09:57:12.478 INFO    admin.api       load complete
2021/12/07 09:57:12.481 INFO    admin   stopped previous server {"address": "tcp/localhost:2019"}
^C2021/12/07 09:59:18.579       INFO    shutting down   {"signal": "SIGINT"}
2021/12/07 09:59:18.579 WARN    exiting; byeee!! 👋     {"signal": "SIGINT"}
2021/12/07 09:59:18.581 INFO    admin   stopped previous server {"address": "tcp/localhost:2019"}
2021/12/07 09:59:18.581 INFO    shutdown complete       {"signal": "SIGINT", "exit_code": 0}

Using the config:

{
        "storage": {
                "module": "file_system",
                "root": "/home/moritz/Desktop/tmp.DeLqOfdK5w/asd"
        },
        "apps": {
                "pki": {
                        "certificate_authorities": {
                                "customca": {
                                        "name": "my custom CA name",
                                        "root_common_name": "custom CA - root",
                                        "intermediate_common_name": "custom CA - intermediate",
                                        "install_trust": false
                                }
                        }
                }
        }
}

Only the CA with the id customca got generated. :tada:

2 Likes

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