# myca-tools Bash helpers for running a simple local root CA, issuing TLS certificates with SANs, and generating Nginx HTTPS reverse-proxy vhosts for internal services. Do not use `.local`. Use `.lan` or a domain you control. ## Placeholders used in this README - `NAME` The service hostname you want to secure. Example: `app.lan`. - `HOST_IP` The local IP address of the server that presents the certificate. In a typical setup this is the machine running Nginx and hosting the service. Example: `192.168.1.50`. - `BACKEND_HOST:PORT` Where Nginx should proxy. Example: `127.0.0.1:8080`. Replace these with your values before running commands. ## Features - Initialise a root CA in `/etc/ssl/myca` - Issue server certificates with DNS and IP SANs - Sign existing CSRs - Show and verify certificates - Deploy certs to `/etc/nginx/ssl` and reload Nginx - Generate a standard HTTPS reverse proxy vhost ## Requirements - Debian or Ubuntu - `openssl` - `nginx` if you want reverse proxying - Root access ## Install ```bash git clone myca-tools cd myca-tools ./install.sh ``` Installs: /usr/local/sbin/myca.sh /usr/local/sbin/mknginx-sni.sh /usr/local/sbin/init-ca.sh Prepares /etc/ssl/myca with certs, csrs, exts, and private. ## Quick start 1. Initialise a root CA if you do not already have one. ```bash sudo init-ca.sh "/CN=My Local Root CA" ``` 2. Trust the CA on this host. ```bash sudo myca.sh trust-ca ``` 3. Issue a cert for your internal service and deploy it to Nginx. ```bash # Replace NAME and HOST_IP sudo myca.sh issue NAME \ --dns NAME --ip HOST_IP --deploy-nginx ``` 4. Create an Nginx vhost that uses the cert and proxies to your backend. ```bash # Replace NAME and BACKEND_HOST:PORT sudo mknginx-sni.sh NAME BACKEND_HOST:PORT ``` 5. Ensure clients resolve the name. ```bash HOST_IP NAME ``` 6. Test. ```bash myca.sh show NAME myca.sh verify NAME curl -Ik https://NAME ``` ## Notes on SANs You can omit --ip HOST_IP if clients always connect by DNS name and do not pin the IP. If clients connect by IP, include that IP in SANs with --ip. You can supply multiple --dns and --ip flags. Scripts myca.sh Helper for issuing, signing, showing, verifying, and deploying certificates. ```bash myca.sh COMMAND [args] Commands: issue NAME [--dns foo --ip 1.2.3.4 ...] [--days N] [--reuse-key] [--deploy-nginx] sign NAME --csr /path/to/file.csr [--dns ... --ip ...] [--days N] show NAME | /path/to/cert.crt verify NAME | /path/to/cert.crt list trust-ca Environment: MYCA_DIR default /etc/ssl/myca NGINX_SSL_DIR default /etc/nginx/ssl ``` Examples: ```bash # Issue new key and cert with SANs sudo myca.sh issue internal-api.lan --dns internal-api.lan --ip HOST_IP # Reissue keeping the same key and deploy to Nginx sudo myca.sh issue wiki.lan --dns wiki.lan --reuse-key --deploy-nginx # Sign an existing CSR sudo myca.sh sign portal.lan --csr /tmp/portal.csr --dns portal.lan --ip 10.0.0.5 # Show and verify myca.sh show wiki.lan myca.sh verify wiki.lan # List issued certs myca.sh list ``` Files are written to: Keys /etc/ssl/myca/private/NAME.key CSRs /etc/ssl/myca/csrs/NAME.csr Certs /etc/ssl/myca/certs/NAME.crt SAN /etc/ssl/myca/exts/NAME.ext CA files expected: /etc/ssl/myca/myCA.pem /etc/ssl/myca/myCA.key /etc/ssl/myca/myCA.srl created on first issuance mknginx-sni.sh Generate a standard HTTPS reverse proxy server block for a given name and backend. ```bash sudo mknginx-sni.sh NAME [BACKEND_HOST:PORT] # writes /etc/nginx/conf.d/NAME.conf # proxies to BACKEND, default 127.0.0.1:8000 # uses /etc/nginx/ssl/NAME.crt and /etc/nginx/ssl/NAME.key ``` Example: ```bash sudo mknginx-sni.sh internal-api.lan 127.0.0.1:9000 ``` init-ca.sh Initialise a new root CA in /etc/ssl/myca. ```bash sudo init-ca.sh "/CN=My Local Root CA" ``` Creates: Root key /etc/ssl/myca/myCA.key 4096 bit Root cert /etc/ssl/myca/myCA.pem valid 10 years Trusting your CA on clients Linux Debian or Ubuntu: ```bash sudo cp /etc/ssl/myca/myCA.pem /usr/local/share/ca-certificates/myCA.crt sudo update-ca-certificates ``` ndows: Import myCA.pem into Local Computer, Trusted Root Certification Authorities. macOS: Import myCA.pem into the System keychain in Keychain Access. Set Always Trust. Browsers must trust the CA or you will see warnings. Directory layout ```vbnet /etc/ssl/myca/ ├── myCA.key root key ├── myCA.pem root certificate ├── myCA.srl serial file ├── certs/ issued certificates ├── csrs/ certificate signing requests ├── exts/ SAN extension files └── private/ server private keys ``` Nginx deploy target: ```swift /etc/nginx/ssl/NAME.crt /etc/nginx/ssl/NAME.key ``` Environment variables Override defaults if needed: ```bash export MYCA_DIR=/srv/pki export NGINX_SSL_DIR=/etc/nginx/ssl ``` Security Back up /etc/ssl/myca/myCA.key offline. Losing it prevents renewal under the same root. Keep /etc/ssl/myca/private permissions intact. Keys are mode 600. Keep this root CA for internal use only. Do not use it on the public internet. Use shorter lifetimes for anything exposed beyond your LAN. Troubleshooting Missing CA: ensure myCA.pem and myCA.key exist under /etc/ssl/myca. verify error:num=20: the client does not trust your CA. Install the CA to the client trust store. Browser still warns after trusting CA: clear the site’s cached cert or restart the browser. Nginx reload fails: run nginx -t and fix the reported error. Licence MIT.