Ziti CLI create CSR not accepting flags and missing ca_name arg

Hey, I’m trying to automate the PKI components creation with Ansible, I’ve done everything but the CSR. (I’ll make a PR on Ziti’s ansible collection soon) I’m trying to manually create one using the CLI first but it looks like it’s not accepting my args.

It looks like it’s missing a --ca-name argument, can’t see how it could figure out in which CA/Intermediate to search for the private key file haha.

It’s also taking a --key-name arguments while other components take --key-file for the private key. I mean in this case, they both refer to the same thing, so I think It would be nice to have the same naming everywhere.

Usage:
  ziti pki create csr [flags]

Flags:
      --csr-file string        File in which to store new CSR (default "csr")
      --csr-name string        Name of CSR (default "NetFoundry Inc. CSR")
      --expire-limit int       Expiration limit in days (default 365)
  -h, --help                   help for csr
      --key-name string        Name of file that contains private key for CSR
      --max-path-len int       Intermediate maximum path length (default -1)
      --private-key-size int   Size of the private key (default 4096)

Global Flags:
      --pki-country string               Country (default "US")
      --pki-locality string              Locality/Location (default "Charlotte")
      --pki-organization string          Organization (default "NetFoundry")
      --pki-organizational-unit string   Organization unit (default "ADV-DEV")
      --pki-province string              Province/State (default "NC")
      --pki-root string                  Directory in which to store CA

Here’s my command :

ziti pki create csr --pki-root "/home/ubuntu/pki_test" --csr-file "csr_test" --csr-name "csr_test" --key-name "key_test"

I’m pretty sure you don’t actually need to make a CSR generally, but perhaps you’re doing something that requires it? What’s the reason you’re trying to make the CSR for?

I don’t need it actually :grin: Just thought I could automate it as I did for ca, intermediate, client, server & private key

Oh, gotcha! I took a look and yeah, it’s a bit strange… I feel like that command is not really working the way I intend it to. It seems like it might not be following / processing the flags properly.

For example, I tried this and got an error. I’ll bring it up with the team and see what the intention was for this subcommand. If it’s not used/needed, it’ll either get removed or fixed:

$ ziti pki create csr --pki-root /tmp/pki/ --key-name my.key --csr-file my.csr.file --csr-name my.csr
? Required flag 'csr-file' not specified; Enter CSR name now: (csr)

I filed this issue to track ziti pki create csr doesn't seem to process flags · Issue #1185 · openziti/ziti · GitHub

1 Like

Thanks !

Also, about the server certificate, does it really needs a private key file (--key-file argument) ?

You’re not using it on the quickstart script :

"${ZITI_BIN_DIR-}/ziti" pki create server --pki-root="${ZITI_PKI}" --ca-name "${ZITI_CA_NAME_local}" \
          --server-file "${file_name}-server" \
          --dns "${dns_allow_list}" --ip "${ip_allow_list}" \
          --server-name "${file_name} server certificate"

Even tho it looks like it’s a mandatory argument on the CLI :

Usage:
  ziti pki create server [flags]

Aliases:
  server, s

Flags:
      --ca-name string         Name of Intermediate CA (within PKI_ROOT) to use to sign the new Server certificate (default "intermediate")
      --dns strings            DNS name(s) to add to Subject Alternate Name (SAN) for new Server certificate
      --expire-limit int       Expiration limit in days (default 365)
  -h, --help                   help for server
      --ip strings             IP addr(s) to add to Subject Alternate Name (SAN) for new Server certificate
      --key-file string        Name of file (under chosen CA) containing private key to use when generating Server certificate
      --max-path-len int       Intermediate maximum path length (default -1)
      --pki-root string        Directory in which PKI resides
      --private-key-size int   Size of the private key (default 4096)
      --server-file string     Name of file (under chosen CA) in which to store new Server certificate and private key (default "server")
      --server-name string     Common Name (CN) to use for new Server certificate (default "NetFoundry Inc. Server")
      --spiffe-id string       Optionally provide the path portion of a SPIFFE id. The trust domain will be taken from the signing certificate.

Global Flags:
      --pki-country string               Country (default "US")
      --pki-locality string              Locality/Location (default "Charlotte")
      --pki-organization string          Organization (default "NetFoundry")
      --pki-organizational-unit string   Organization unit (default "ADV-DEV")
      --pki-province string              Province/State (default "NC")

Looks like it’s optional and by default it uses the CA’s private key (–key-file == --ca-name by default). Maybe it could be worth to add to the cli manual.

Is it the same for the client ?

It’s definitely necessary to have a key but if not supplied, I expect a private key is just being generated. Arguably that server cert could use the same key but it’s not vital as you’ve discovered.

For the client it’s definitely important to use the same key. I think what happens is the quickstart makes the server cert, which implicitly creates the key, then the key is used when making the client cert

Alright thanks. Last question about the quickstart, is the edge controller CA really used ? I mean I’m following along your video + sh script and a running instance of a Openziti network and I don’t see the Edge Controller CA + ZITI_PKI_CTRL_EDGE_ROOTCA_NAME env = ZITI_PKI_CTRL_ROOTCA_NAME. So the code below isn’t actually creating two CAs isn’t it ?

_pki_create_ca "${ZITI_PKI_CTRL_ROOTCA_NAME}"
_pki_create_ca "${ZITI_PKI_CTRL_EDGE_ROOTCA_NAME}"

I’m only seeing the Controller and signing CAs + their intermediates :

ubuntu@instance-20230616-2057:~/.ziti/quickstart/instance-20230616-2057/pki$ ls
cas.pem                              instance-20230616-2057-signing-intermediate                        routers
instance-20230616-2057-intermediate  instance-20230616-2057-signing-intermediate_spurious_intermediate
instance-20230616-2057-root-ca       instance-20230616-2057-signing-root-ca

It's definitely used. It goes into the enrollment bundle when identities enroll. If you curl to the well-known/est/cacerts endpoint, pass that through base64, then openssl pkcs7 you'll see your certs in there. Big long example script (replace localhost accordingly):

curl -sSfk https://localhost:8441/.well-known/est/cacerts | openssl base64 -d | openssl pkcs7 -inform DER -outform PEM -print_certs

Yes it most definitely does. The quickstart was originally intended to be used for educational purposes. I thought people would try it out, inspect the config files and learn/explore from there. In reality, few do that! :slight_smile: As a learning mechanism, I had intentionally used/created the three different CA's that can exist in the controller's config. There's:

  • ZITI_PKI_CTRL_ROOTCA_NAME: The CA for the control plane (router to controller, router to router etc)
  • ZITI_PKI_CTRL_EDGE_ROOTCA_NAME: The CA for the edge api (management and client)
  • ZITI_PKI_SIGNER_ROOTCA_NAME: The CA for the identities OpenZiti creates

I can't explain why your PKI seems to be 'missing' some. On my freshly installed docker compose env, I see five:

ls -l $ZITI_PKI
total 32
-rw-r--r-- 1 ziti ziti 8725 Jul  5 22:19 cas.pem
drwxr-xr-x 5 ziti ziti 4096 Jul  5 22:19 ec2-13-58-222-94.us-east-2.compute.amazonaws.com-intermediate
drwxr-xr-x 5 ziti ziti 4096 Jul  5 22:19 ec2-13-58-222-94.us-east-2.compute.amazonaws.com-root-ca
drwxr-xr-x 5 ziti ziti 4096 Jul  5 22:19 ziti-signing-intermediate
drwxr-xr-x 5 ziti ziti 4096 Jul  5 22:19 ziti-signing-intermediate_spurious_intermediate
drwxr-xr-x 5 ziti ziti 4096 Jul  5 22:19 ziti-signing-root-ca

If you issue 'find' commands like this, I'd have expected you to find three results:

ziti@80b2e8b125e3:/persistent/pki$ find $ZITI_PKI -name $ZITI_PKI_CTRL_ROOTCA_NAME
/persistent/pki/ec2-13-58-222-94.us-east-2.compute.amazonaws.com-root-ca
ziti@80b2e8b125e3:/persistent/pki$ find $ZITI_PKI -name $ZITI_PKI_CTRL_EDGE_ROOTCA_NAME
/persistent/pki/ec2-13-58-222-94.us-east-2.compute.amazonaws.com-root-ca
ziti@80b2e8b125e3:/persistent/pki$ find $ZITI_PKI -name $ZITI_PKI_SIGNER_ROOTCA_NAME
/persistent/pki/ziti-signing-root-ca

I also have 5 CA/Intermediate actually.

ubuntu@instance-20230616-2057:~/ziti$ ls -l ~/.ziti/quickstart/instance-20230616-2057/pki
total 36
-rw-rw-r-- 1 ubuntu ubuntu 8612 Jun 16 19:29 cas.pem
drwxr-xr-x 5 ubuntu ubuntu 4096 Jun 16 19:29 instance-20230616-2057-intermediate
drwxr-xr-x 5 ubuntu ubuntu 4096 Jun 16 19:28 instance-20230616-2057-root-ca
drwxr-xr-x 5 ubuntu ubuntu 4096 Jun 16 19:29 instance-20230616-2057-signing-intermediate
drwxr-xr-x 5 ubuntu ubuntu 4096 Jun 16 19:29 instance-20230616-2057-signing-intermediate_spurious_intermediate
drwxr-xr-x 5 ubuntu ubuntu 4096 Jun 16 19:28 instance-20230616-2057-signing-root-ca
drwxrwxr-x 3 ubuntu ubuntu 4096 Jun 16 19:29 routers

It looks like ZITI_PKI_CTRL_ROOTCA_NAME and ZITI_PKI_CTRL_EDGE_ROOTCA_NAME have the same value which is "ec2-13-58-222-94.us-east-2.compute.amazonaws.com-root-ca" in your case and "instance-20230616-2057-root-ca" in mine.

Given that, If we try to create two CAs with the same name within the same PKI root, it will fail.

Looking back, I see from your post before you indeed showed that you had five! The "ls" vs "ls -l" made my brain think there were only three! :man_facepalming: My bad :wink:

Ah. Interesting! I've never noticed. I would not have expected that. I would have expected one to have "edge" in there and one to not. I wonder when that bug came to be. It might have been there all along.

That would explain why the quickstart works when your automation does not, indeed. I'm doing quickstart related work. I'll poke around in there and see.

In the meantime, I must admit I've lost track of this issue. Is the original question you posted still relevant or have we both explored this enough to understand what's probably going on for you to fix the missing bits?