# SSL Certificate — zet.home.arpa Let's Encrypt certificate for `kenjim.com` subdomains, issued and renewed via acme.sh using GoDaddy DNS-01 challenge. ## Overview | Field | Value | |-------|-------| | **CA** | Let's Encrypt | | **Tool** | acme.sh v3.1.4 | | **Challenge** | DNS-01 via GoDaddy API | | **Key type** | ECC (default in acme.sh v3) | | **Validity** | 90 days (auto-renewed at ~60 days) | | **Installed to** | `/etc/nginx/ssl/kenjim.com/` | | **acme.sh data** | `~/.acme.sh/zet.kenjim.com_ecc/` | ## Covered Domains (SANs) - `zet.kenjim.com` (primary) - `git.kenjim.com` - `www.kenjim.com` - `kenji.kenjim.com` - `gt.kenjim.com` ## GoDaddy API Credentials Stored by acme.sh in `~/.acme.sh/account.conf` after first use. Only needs to be re-exported if rotating the API key. The API key used is named **"Claude"** in GoDaddy's developer portal (developer.godaddy.com → API Keys). To re-export credentials for a manual reissue: ```bash export GD_Key='your-key' export GD_Secret='your-secret' ``` **Never paste credentials into chat or commit them to this repo.** ## Installed Certificate Files | File | Purpose | |------|---------| | `/etc/nginx/ssl/kenjim.com/fullchain.pem` | Certificate + intermediates (used by nginx) | | `/etc/nginx/ssl/kenjim.com/key.pem` | Private key (used by nginx) | Directory ownership: `kenjim:www-data`, mode `750`. Files readable by nginx (`www-data` group). ## Auto-Renewal acme.sh installs a cron job at install time: ```bash crontab -l | grep acme # verify cron entry exists ``` On renewal acme.sh: 1. Adds `_acme-challenge` TXT records to GoDaddy DNS via API 2. Requests new cert from Let's Encrypt 3. Copies cert files to `/etc/nginx/ssl/kenjim.com/` 4. Runs `sudo systemctl reload nginx` 5. Cleans up TXT records The sudoers rule that allows passwordless nginx reload: ``` /etc/sudoers.d/acme-nginx-reload: kenjim ALL=(ALL) NOPASSWD: /bin/systemctl reload nginx ``` ## Manual Reissue Only needed if the cert is lost or domains change: ```bash export GD_Key='your-key' export GD_Secret='your-secret' ~/.acme.sh/acme.sh --issue \ --server letsencrypt \ --dns dns_gd \ -d zet.kenjim.com \ -d git.kenjim.com \ -d www.kenjim.com \ -d kenji.kenjim.com \ -d gt.kenjim.com ~/.acme.sh/acme.sh --install-cert \ -d zet.kenjim.com \ --fullchain-file /etc/nginx/ssl/kenjim.com/fullchain.pem \ --key-file /etc/nginx/ssl/kenjim.com/key.pem \ --reloadcmd "sudo systemctl reload nginx" ``` Note: always pass `--server letsencrypt` — acme.sh v3 defaults to ZeroSSL which has a 24-hour retry delay incompatible with acme.sh's timeout. ## Verify Certificate ```bash # Check cert served by nginx locally curl -sv --resolve git.kenjim.com:443:172.27.0.35 https://git.kenjim.com 2>&1 \ | grep -E "subject|issuer|subjectAltName|SSL connection" # Check expiry ~/.acme.sh/acme.sh --list # Check from outside the LAN curl -sv https://git.kenjim.com 2>&1 | grep -E "subject|issuer|< HTTP" ``` ## DNS Setup Public DNS uses CNAMEs to a DDNS-managed A record: | Record | Type | Value | |--------|------|-------| | `lair.kenjim.com` | A | `` — updated by pfSense DDNS | | `zet.kenjim.com` | CNAME | `lair.kenjim.com` | | `git.kenjim.com` | CNAME | `lair.kenjim.com` | | `www.kenjim.com` | CNAME | `lair.kenjim.com` | | `kenji.kenjim.com` | CNAME | `lair.kenjim.com` | | `gt.kenjim.com` | CNAME | `lair.kenjim.com` | pfSense Dynamic DNS keeps `lair.kenjim.com` updated whenever the ISP WAN IP changes. All subdomains follow automatically via their CNAMEs. See [../nginx/](../nginx/) for how the cert is used.