I'm definitely open to learning how to do things better, and I have no doubt that some of what I'm doing is wrong - after all, this whole thing started as a homelab-turned-homeprod learning experience.
I think the proper way to do certs is to have the server (Web, VPN, whatever) create a certificate signing request and private key on the server, send the signing request to the CA to sign it, and then install the resulting signed cert on the server. Is this correct?
What I'm finding in some cases is that there are cases where this just won't work. For example, my QNAP NAS allows me to either create a self-signed certificate (I don't want this, I want it signed by my CA), get one from Let's Encrypt (same issue), or upload certificate, private key, and optional intermediate CA certificate files (and we're back to moving private keys). This is a limitation of QNAP's GUI for sure, but it's not unique to QNAP.
Similarly, I'm not sure how I'd generate the certificate plus private key on an iOS device and submit it for signing (the VPN scenario). This one particularly bothers me because the .mobileconfig file ends up being the key to the castle. Ideally I'd like the client to be authenticated with both a user-specific certificate and EAP, but I don't think iOS supports this. I haven't quite gone very far down this rabbit hole, so it's possible that I'm missing something.
When I finally secure my internal web server (which acts as a reverse proxy for all of my internal services), I'll try the CSR approach for the learning experience. This approach should also work fine on my VPN server.