summaryrefslogtreecommitdiffstats
path: root/docs/HTTPS.md
blob: 2c1e13c4dcd25541aa1d326e5316757f3eda03f9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# MeshBay — HTTPS Certificate Setup

> Server: meshbay.org (Ubuntu 26.04, OVH VPS)
> Proxy: Caddy 2.x
> Status: active as of 2026-08-09

---

## What was done

### 1. Install Caddy

Caddy is a modern web server that handles TLS certificate issuance and renewal automatically. No manual interaction with Let's Encrypt is required.

```bash
sudo apt install -y caddy
sudo systemctl enable --now caddy
```

### 2. Configure the Caddyfile

`/etc/caddy/Caddyfile`:

```
www.meshbay.org {
    redir https://meshbay.org{uri} permanent
}

meshbay.org {
    reverse_proxy 127.0.0.1:8000
}
```

What this does:
- `www.meshbay.org` → permanent 301 redirect to `meshbay.org` (canonical URL)
- `meshbay.org` → proxies all traffic to the uvicorn/FastAPI hub running on `127.0.0.1:8000`
- Caddy automatically handles TLS termination, HTTPS upgrade (HTTP→HTTPS redirect), and HTTP/2

### 3. Caddy obtains certificates automatically

On first start or after a Caddyfile change, Caddy:
1. Registers with Let's Encrypt (ACME protocol)
2. Proves domain ownership via TLS-ALPN-01 challenge (no DNS or port 80 configuration needed)
3. Downloads the certificate chain
4. Stores certificates in `/var/lib/caddy/.local/share/caddy/`
5. Renews certificates automatically ~30 days before expiry

```bash
sudo systemctl reload caddy   # apply Caddyfile changes
sudo systemctl status caddy   # check logs
```

The certificate for `www.meshbay.org` was obtained in ~4 seconds after the Caddyfile update.

---

## Can we get a 1-year certificate?

**Short answer: No, not from Let's Encrypt — and that's fine.**

### Current situation (2026)

Let's Encrypt certificates are valid for **90 days**. This is intentional:
- Short-lived certificates limit exposure if a private key is compromised
- Automation (via ACME) makes renewal transparent — no manual work needed
- Caddy renews automatically ~30 days before expiry

Since Caddy handles renewal without any intervention, the 90-day limit is **completely transparent** to users and operators. The certificate is always valid; you will never see an expiry warning.

### Why not 1 year?

As of March 2026, the CA/Browser Forum voted to progressively reduce maximum certificate validity:
- 2026: 200 days max (not yet enforced by all CAs)
- 2027: 100 days max
- 2029: 47 days max

The industry direction is **shorter**, not longer. Paid CAs (DigiCert, Sectigo) currently still issue 1-year certificates, but this will end within the next few years.

### If you absolutely need a longer-lived certificate

Options (all have trade-offs):

| Option | Validity | Cost | Effort |
|---|---|---|---|
| Let's Encrypt + Caddy | 90 days (auto-renewed) | Free | None |
| ZeroSSL (ACME) | 90 days (auto-renewed) | Free | None |
| DigiCert / Sectigo | Up to 1 year (for now) | ~€50-150/year | Manual renewal |
| Self-signed | Any duration | Free | Clients will warn |

**Recommendation: keep Let's Encrypt + Caddy.** It is effectively infinite-duration from an operational standpoint. Switching to a paid CA for a longer nominal validity provides no practical benefit and adds cost and manual renewal risk.

---

## Troubleshooting

```bash
# Check Caddy status and recent logs
sudo systemctl status caddy --no-pager -l

# Validate the Caddyfile syntax before reloading
caddy validate --config /etc/caddy/Caddyfile

# Force certificate renewal (normally not needed)
sudo systemctl stop caddy
sudo caddy run --config /etc/caddy/Caddyfile

# View stored certificates
sudo ls /var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/
```

## Current certificate info

```bash
# Check certificate from the outside
echo | openssl s_client -connect meshbay.org:443 -servername meshbay.org 2>/dev/null \
  | openssl x509 -noout -dates -subject
```

---

## DNS requirements

For Let's Encrypt to work, DNS must resolve to this server **before** Caddy requests the certificate.

- `meshbay.org`     → A record → `164.132.246.44`
- `www.meshbay.org` → A record → `164.132.246.44` (or CNAME to `meshbay.org`)

If the DNS is not pointing here, the TLS-ALPN-01 challenge will fail silently and Caddy will retry periodically.

---

## Security notes

- Caddy listens on ports 80 and 443 (allowed in UFW)
- HTTP requests on port 80 are automatically redirected to HTTPS by Caddy
- The hub (uvicorn) listens only on `127.0.0.1:8000` — not directly reachable from the internet
- Caddy enforces TLS 1.2+ by default (TLS 1.3 preferred)
- Port 8000 is NOT open in UFW (Caddy proxies internally)