Make websocket transport secure by default
This commit is contained in:
@@ -11,7 +11,7 @@ Chat Grid is designed to be run on a secure server with users connecting via a w
|
|||||||
```bash
|
```bash
|
||||||
cd server
|
cd server
|
||||||
cp config.example.toml config.toml
|
cp config.example.toml config.toml
|
||||||
uv run python main.py
|
uv run python main.py --allow-insecure-ws
|
||||||
```
|
```
|
||||||
|
|
||||||
2) Start client
|
2) Start client
|
||||||
@@ -32,6 +32,7 @@ Notes:
|
|||||||
Common server overrides:
|
Common server overrides:
|
||||||
- `uv run python main.py --config /path/to/config.toml`
|
- `uv run python main.py --config /path/to/config.toml`
|
||||||
- `uv run python main.py --host 0.0.0.0 --port 9000`
|
- `uv run python main.py --host 0.0.0.0 --port 9000`
|
||||||
|
- `uv run python main.py --allow-insecure-ws` (local/dev without TLS)
|
||||||
- `uv run python main.py --ssl-cert /path/fullchain.pem --ssl-key /path/privkey.pem`
|
- `uv run python main.py --ssl-cert /path/fullchain.pem --ssl-key /path/privkey.pem`
|
||||||
- `uv run python main.py --bootstrap-admin` (one-time admin creation)
|
- `uv run python main.py --bootstrap-admin` (one-time admin creation)
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /home/jjm/code/chgrid/server
|
cd /home/jjm/code/chgrid/server
|
||||||
.venv/bin/python main.py
|
.venv/bin/python main.py --allow-insecure-ws
|
||||||
```
|
```
|
||||||
|
|
||||||
## Start Client
|
## Start Client
|
||||||
@@ -19,6 +19,7 @@ Open: `http://localhost:5173`
|
|||||||
Defaults:
|
Defaults:
|
||||||
- Server reads `config.toml` automatically when present.
|
- Server reads `config.toml` automatically when present.
|
||||||
- Server default bind/port is `127.0.0.1:8765`.
|
- Server default bind/port is `127.0.0.1:8765`.
|
||||||
|
- Server defaults to TLS-required unless you set `network.allow_insecure_ws=true` or pass `--allow-insecure-ws` for local/dev.
|
||||||
- Client dev default is `localhost:5173`.
|
- Client dev default is `localhost:5173`.
|
||||||
- Auth requires `CHGRID_AUTH_SECRET` in environment.
|
- Auth requires `CHGRID_AUTH_SECRET` in environment.
|
||||||
|
|
||||||
@@ -28,7 +29,7 @@ Server:
|
|||||||
```bash
|
```bash
|
||||||
lsof -tiTCP:8765 -sTCP:LISTEN | xargs -r kill
|
lsof -tiTCP:8765 -sTCP:LISTEN | xargs -r kill
|
||||||
cd /home/jjm/code/chgrid/server
|
cd /home/jjm/code/chgrid/server
|
||||||
nohup .venv/bin/python main.py > /tmp/chgrid-server.log 2>&1 &
|
nohup .venv/bin/python main.py --allow-insecure-ws > /tmp/chgrid-server.log 2>&1 &
|
||||||
```
|
```
|
||||||
|
|
||||||
Client:
|
Client:
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ Key options:
|
|||||||
- `tls.cert_file`, `tls.key_file`
|
- `tls.cert_file`, `tls.key_file`
|
||||||
|
|
||||||
If `network.allow_insecure_ws = false`, TLS cert/key are required and server runs as `wss://`.
|
If `network.allow_insecure_ws = false`, TLS cert/key are required and server runs as `wss://`.
|
||||||
|
For local/dev without TLS, either set `network.allow_insecure_ws = true` or pass `--allow-insecure-ws`.
|
||||||
|
|
||||||
## Run
|
## Run
|
||||||
|
|
||||||
@@ -31,5 +32,6 @@ python main.py --config config.toml
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
python main.py --config config.toml --host 127.0.0.1 --port 8765
|
python main.py --config config.toml --host 127.0.0.1 --port 8765
|
||||||
|
python main.py --config config.toml --allow-insecure-ws
|
||||||
python main.py --config config.toml --ssl-cert /path/cert.pem --ssl-key /path/key.pem
|
python main.py --config config.toml --ssl-cert /path/cert.pem --ssl-key /path/key.pem
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class NetworkConfigSection(BaseModel):
|
|||||||
"""Network transport and safety limits."""
|
"""Network transport and safety limits."""
|
||||||
|
|
||||||
max_message_bytes: int = Field(default=2_000_000, gt=0)
|
max_message_bytes: int = Field(default=2_000_000, gt=0)
|
||||||
allow_insecure_ws: bool = True
|
allow_insecure_ws: bool = False
|
||||||
|
|
||||||
|
|
||||||
class TlsConfigSection(BaseModel):
|
class TlsConfigSection(BaseModel):
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ port = 8765
|
|||||||
[network]
|
[network]
|
||||||
# Maximum inbound websocket message size in bytes.
|
# Maximum inbound websocket message size in bytes.
|
||||||
max_message_bytes = 2000000
|
max_message_bytes = 2000000
|
||||||
# If false, TLS cert and key are required and server runs as wss:// only.
|
# Secure-by-default: TLS is required unless you explicitly set this to true for local/dev.
|
||||||
allow_insecure_ws = true
|
allow_insecure_ws = false
|
||||||
|
|
||||||
[tls]
|
[tls]
|
||||||
# Required when allow_insecure_ws = false.
|
# Required when allow_insecure_ws = false.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from app.config import load_config
|
|||||||
def test_load_config_defaults_when_path_none() -> None:
|
def test_load_config_defaults_when_path_none() -> None:
|
||||||
cfg = load_config(None)
|
cfg = load_config(None)
|
||||||
assert cfg.server.bind_ip == "127.0.0.1"
|
assert cfg.server.bind_ip == "127.0.0.1"
|
||||||
assert cfg.network.allow_insecure_ws is True
|
assert cfg.network.allow_insecure_ws is False
|
||||||
assert cfg.storage.state_file == "runtime/items.json"
|
assert cfg.storage.state_file == "runtime/items.json"
|
||||||
assert cfg.storage.state_save_debounce_ms == 200
|
assert cfg.storage.state_save_debounce_ms == 200
|
||||||
assert cfg.storage.state_save_max_delay_ms == 1000
|
assert cfg.storage.state_save_max_delay_ms == 1000
|
||||||
@@ -31,6 +31,9 @@ def test_load_config_reads_state_save_timing(tmp_path: Path) -> None:
|
|||||||
config_path = tmp_path / "config.toml"
|
config_path = tmp_path / "config.toml"
|
||||||
config_path.write_text(
|
config_path.write_text(
|
||||||
"""
|
"""
|
||||||
|
[network]
|
||||||
|
allow_insecure_ws = true
|
||||||
|
|
||||||
[storage]
|
[storage]
|
||||||
state_file = "runtime/items.json"
|
state_file = "runtime/items.json"
|
||||||
state_save_debounce_ms = 150
|
state_save_debounce_ms = 150
|
||||||
|
|||||||
Reference in New Issue
Block a user