Skip to content
Merged
1 change: 1 addition & 0 deletions changes/pr-447.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[ATS] Add local SSL support
1 change: 1 addition & 0 deletions docs/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

- [Andrew's Software](./intro.md)
- [Machine Management](./machines.md)
- [Local SSL Setup](./local-ssl-setup.md)
- [RFCs](./rfcs/rfcs.md)
- [Continuous OS Deployment](./rfcs/002.oscd.md)
- [C++ Packages](./cpp/cpp.md)
Expand Down
169 changes: 169 additions & 0 deletions docs/src/local-ssl-setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# Local SSL Setup for LAN Access

This guide explains how to set up HTTPS access to your server from devices on your local network (especially your phone).

## Overview

The server supports **both HTTP and HTTPS** connections:
- **HTTP**: `http://ats.local:80` (or your hostname)
- **HTTPS**: `https://ats.local:443` (or your hostname)

There is **no automatic redirect** from HTTP to HTTPS - you can use either protocol.

## Quick Start

### 1. Generate SSL Certificates

Run the certificate generation command (automatically available on servers with `runWebServer = true`):

```bash
generate-local-ssl-certs
```

This will auto-detect your LAN IP address and create:
- `~/secrets/vpn/rootCA.pem` - Root CA certificate (**install this on your phone**)
- `~/secrets/vpn/rootCA-key.pem` - Root CA private key (keep secret!)
- `~/secrets/vpn/chain.pem` - Server certificate
- `~/secrets/vpn/key.pem` - Server private key

You can also specify your server IP manually:
```bash
generate-local-ssl-certs 192.168.1.100
```

### 2. Install CA Certificate on Your Phone

To avoid SSL warnings, you **must** install the root CA certificate on your phone.

#### Android

1. Transfer `~/secrets/vpn/rootCA.pem` to your phone (via email, USB, etc.)
2. Open **Settings** → **Security** → **Encryption & credentials**
3. Tap **Install a certificate** → **CA certificate**
4. Select the `rootCA.pem` file
5. Give it a name like "ATS Local CA" or "[hostname] Local CA"

#### iPhone/iPad

1. Transfer `rootCA.pem` to your device (email or AirDrop)
2. Open the file - iOS will prompt to install a profile
3. Go to **Settings** → **General** → **VPN & Device Management**
4. Install the profile
5. Go to **Settings** → **General** → **About** → **Certificate Trust Settings**
6. Enable **full trust** for the certificate

### 3. Access Your Server

Once the CA is installed, you can access your server via HTTPS:

```
https://ats.local:443
```

Or use your server's IP address:
```
https://192.168.1.100:443
```

You can also use HTTP if you prefer:
```
http://ats.local:80
```

## Technical Details

### Certificate Validity

- The certificates are valid for **~825 days** (mkcert default)
- They're valid for:
- `[hostname].local`
- `*.[hostname].local` (wildcard for subdomains)
- `localhost`
- `127.0.0.1`
- Your LAN IP address

### How It Works

1. **mkcert** creates a local CA (certificate authority)
2. The server certificate is signed by this CA
3. By installing the CA certificate on your phone, your phone trusts any certificate signed by that CA
4. This is the same mechanism used by commercial CAs like Let's Encrypt

### Nginx Configuration

The nginx server is configured to:
- Listen on port 80 (HTTP)
- Listen on port 443 (HTTPS with SSL)
- **NOT** redirect HTTP to HTTPS (both are supported)
- Run as user `andrew` with group `dev`

The SSL certificate files are stored in `~/secrets/vpn/`:
- `chain.pem` - Server certificate (readable by nginx)
- `key.pem` - Server private key (readable by nginx, mode 600)

### Backup with rcrsync

Since the certificates are in `~/secrets/`, they will be backed up by the `rcrsync` tool (if configured). This means:
- You don't lose your CA when backing up
- All your devices stay trusted after a restore
- You don't need to reinstall CA certificates on your devices after a restore

## Troubleshooting

### SSL Warning on Phone

If you see "Your connection is not private" or similar:
- Verify you installed the **CA certificate** (`rootCA.pem`), not the server certificate
- On iOS, ensure you enabled **full trust** in Certificate Trust Settings
- Try clearing Chrome's cache or restarting the browser

### Certificate Expired

If the certificate expires:
```bash
generate-local-ssl-certs
```

The script will backup old certificates and create new ones.

### Connection Refused

- Verify the firewall allows ports 80 and 443:
```bash
sudo iptables -L -n | grep -E '80|443'
```
- Check nginx is running:
```bash
systemctl status nginx
```
- Verify the server services are running:
```bash
systemctl status stampserver
systemctl status rankserver
```

### Wrong IP Address

If your server's LAN IP changed:
```bash
generate-local-ssl-certs [new-ip-address]
```

## Security Notes

- **Private key security**: The `key.pem` and `rootCA-key.pem` files should be kept secret. They're stored in `~/secrets/` with restricted permissions.
- **CA installation**: Only install the CA certificate on devices you own and trust.
- **Local network only**: These certificates are only for local LAN access. They won't work over the internet.
- **Self-signed**: These are self-signed certificates. They provide encryption but not identity verification (unlike commercial CAs).

## File Permissions

The certificate files have the following permissions:
```
-rw-r--r-- chain.pem (644) - Server certificate, readable by all
-rw------- key.pem (600) - Server private key, readable only by owner
-rw-r--r-- rootCA.pem (644) - CA certificate, readable by all
-rw------- rootCA-key.pem (600) - CA private key, readable only by owner
```

Nginx runs as user `andrew` with group `dev`, so it can read all these files.
76 changes: 76 additions & 0 deletions docs/src/machines.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,82 @@ nixos-generate -f iso -c /path/to/personal/configuration.nix [-I nixpkgs=/path/t
sudo dd if=/path/to/nixos.iso of=/dev/sdX bs=4M conv=fsync status=progress
```

## Local SSL Setup for HTTPS Access

For machines configured with `runWebServer = true` (like ATS), you can enable HTTPS access from devices on your local network (especially phones) to avoid browser security warnings.

### Quick Start

1. **Generate SSL certificates** on the server:
```bash
generate-local-ssl-certs
```

The script will auto-detect your LAN IP address and create certificates in `~/secrets/vpn/`.

If you need to specify a different IP address:
```bash
generate-local-ssl-certs 192.168.1.100
```

2. **Install the CA certificate on your client devices**:

Transfer `~/secrets/vpn/rootCA.pem` to your phone and install it:

**Android:**
- Settings → Security → Encryption & credentials → Install a certificate
- Choose "CA certificate" and select `rootCA.pem`
- Give it a name like "ATS Local CA"

**iPhone/iPad:**
- Email or AirDrop `rootCA.pem` to your device
- Open the file to install the profile
- Settings → General → VPN & Device Management → Install the profile
- Settings → General → About → Certificate Trust Settings → Enable full trust

3. **Access your server via HTTPS**:
```
https://ats.local:443
```

Or use HTTP if you prefer (no automatic redirect):
```
http://ats.local:80
```

### How It Works

- The nginx server listens on **both** HTTP (port 80) and HTTPS (port 443)
- There is **no automatic redirect** from HTTP to HTTPS - both protocols are supported
- The certificates are valid for:
- `[hostname].local` (e.g., `ats.local`)
- `*.[hostname].local` (wildcard for subdomains)
- `localhost`, `127.0.0.1`, and your LAN IP address
- Certificates are stored in `~/secrets/vpn/` and backed up by `rcrsync`
- Certificates expire after ~825 days and can be regenerated anytime

### Regenerating Certificates

If your server IP changes or certificates expire:
```bash
generate-local-ssl-certs [new-ip-address]
```

The script will backup old certificates and create new ones. You won't need to reinstall the CA on your devices if you're replacing server certificates signed by the same CA.

### Troubleshooting

**SSL warnings still appear:**
- Verify you installed `rootCA.pem` (the CA certificate), not `chain.pem`
- On iOS, ensure you enabled full trust in Certificate Trust Settings
- Try clearing browser cache or restarting the browser

**Connection refused:**
- Check firewall allows ports 80 and 443: `sudo iptables -L -n | grep -E '80|443'`
- Verify nginx is running: `systemctl status nginx`

See [Local SSL Setup](./local-ssl-setup.md) for complete documentation.

## Miscellaneous

### Cloud Syncing
Expand Down
Loading
Loading