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>
This commit is contained in:
124
zet.home.arpa/ssl/README.md
Normal file
124
zet.home.arpa/ssl/README.md
Normal file
@@ -0,0 +1,124 @@
|
||||
# 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 | `<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/](../nginx/) for how the cert is used.
|
||||
Reference in New Issue
Block a user