summaryrefslogtreecommitdiffstats
path: root/docs/SERVER_SETUP.md
blob: 700a12ef5a1e8290dfcdfa75fc6489230a854530 (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
# Server setup

The server speaks TLS and needs a PKCS#12 identity (`identity.p12`) plus the
PEM key/certificate used to build it. The files are read from the current
working directory.

## Quick start

From the project root:

```sh
cargo run --bin server -- --init
cargo run --bin server
```

`--init` creates a self-signed development identity and exits. The next
command starts the server on `127.0.0.1:11525`.

If `identity.p12` is missing at startup, the server now prints these same
instructions instead of only the raw OS error.

## What `--init` creates

| File | Purpose |
| --- | --- |
| `identity.p12` | PKCS#12 identity loaded by `native-tls`. Empty password. Uses PBE-SHA1-3DES and a SHA-1 MAC so the Windows SChannel backend can load it. |
| `key.pem` | RSA private key used to build the identity. Not read at runtime. |
| `cert.pem` | Public certificate, useful for inspection. |

On Unix, `identity.p12` and `key.pem` are set to mode `0600`. All three are
ignored by git (`*.p12`, `*.pem`, `*.key`).

## Manual setup

If `openssl` is not installed or you want to control the certificate:

```sh
openssl req -x509 -newkey rsa:2048 \
  -keyout key.pem -out cert.pem \
  -days 3650 -nodes -subj "/CN=localhost"

openssl pkcs12 -export -out identity.p12 \
  -inkey key.pem -in cert.pem -passout pass:
```

The password must be empty because the server calls
`Identity::from_pkcs12(&data, "")`.

## Running

```sh
# default: 127.0.0.1:11525
cargo run --bin server

# listen on all interfaces
cargo run --bin server -- -i 0.0.0.0 -p 11525

# show options
cargo run --bin server -- --help
```

Then start the client in another terminal:

```sh
cargo run --bin client
```

On first contact the client prints the SPKI fingerprint and pins it. If you
regenerate the server identity, the client will reject the new key; run
`forget-host` in the client if the change is intentional.

Credentials are stored against the pinned fingerprint, not the address. Log in
once through `127.0.0.1:11525` and connecting through the machine's LAN address
will authenticate automatically, because both addresses present the same key.
`forget-host` removes one address; the stored login is only dropped when the
last address for that key is forgotten.

## Database

The server creates `server.db` in the current directory on first use. It holds
users, balances, and the per-game `plays` audit. The client keeps its own
`client.db` for host fingerprints and stored credentials in
`$XDG_DATA_HOME/zagan-bet/` (usually `~/.local/share/zagan-bet/`); pass
`-d <dir>` to keep it somewhere else. There are no schema
migrations while the app is in alpha: a schema change means deleting both files.

During development, delete both files to reset users, balances, history, and
trust:

```sh
rm -f server.db client.db
```

The `plays` schema is not auto-migrated from the old slots-only shape; a stale
database must be removed.

## Windows

`--init` shells out to `openssl`, so OpenSSL must be installed and on `PATH`
(Git for Windows, WSL, or a standalone OpenSSL build). The generated files work
the same way. `--init` uses SChannel-friendly PKCS#12 algorithms; if you build
the identity by hand on Windows, use:

```sh
openssl pkcs12 -export -out identity.p12 -inkey key.pem -in cert.pem \
  -passout pass: -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES -macalg sha1
```

## Security notes

- This is a self-signed development identity with an empty PKCS#12 password.
  Treat `key.pem` and `identity.p12` as secrets and do not commit them.
- The trust model is TOFU: clients pin the SPKI fingerprint on first contact.
  A changed key is a loud error, not an automatic re-trust.
- For a public deployment, use a CA-issued certificate and protect the
  PKCS#12 with a password; the current server code expects an empty password.

## Troubleshooting

| Symptom | Fix |
| --- | --- |
| `Failed to initialize TLS: Could not read TLS identity` | Run `cargo run --bin server -- --init`. |
| `Address already in use` | Stop the other server or pass `-p <port>`. |
| Client says `HOST KEY CHANGED` | The server certificate changed. If intentional, run `forget-host` in the client. |
| `openssl` not found | Install OpenSSL or use the manual commands on a machine that has it. |