Files
Kenji M 7c4c786e7b zet.home.arpa: document all services and SSL/nginx setup
- Server overview (README.md) with services, storage, and network summary
- Storage layout with disk/fstab/mount details (storage.md)
- Service docs: Samba, NFS, Squid, Pi-hole (with DHCP/split-DNS notes)
- Let's Encrypt cert via acme.sh + GoDaddy DNS-01 (ssl/)
- nginx SSL reverse proxy config and virtual host guide (nginx/)
- Pi-hole moved to port 8081; split DNS overrides documented for both
  Pi-hole and pfSense Unbound to avoid hairpin NAT issues

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 14:37:04 +00:00
..

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:

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:

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:

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

# 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 <WAN IP> — 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/ for how the cert is used.