mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 19:26:48 +00:00
fix(console): keep socketiod behind nginx and off by default there too
- Comment out the nginx /socket.io/ location: a firewall on 6081 does not protect a console that nginx proxies on 80/443. - Default SOCKETIO_HOST to 127.0.0.1. - README: short enable steps and the changes existing installs need. - test_socketiod_disabled writes its settings module to a temporary directory instead of the source tree.
This commit is contained in:
parent
1547e58e55
commit
4252ad9280
4 changed files with 28 additions and 31 deletions
13
README.md
13
README.md
|
|
@ -278,7 +278,7 @@ python manage.py runserver 0.0.0.0:8000 --settings=webvirtcloud.settings-dev --n
|
|||
|
||||
Open `http://127.0.0.1:8000`. `settings-dev` enables `DEBUG` and the Django Debug Toolbar. `--nostatic` is required: the CSS/JS live in `static/` (`STATIC_ROOT`), which WhiteNoise serves but runserver's own static handler does not.
|
||||
|
||||
For the browser console, start the websocket proxy in a separate terminal: `python console/novncd` (VNC, port 6080). The serial console (`python console/socketiod`, port 6081) is disabled by default; see [Serial Console](#serial-console-disabled-by-default).
|
||||
For the browser console, run `python console/novncd` (VNC, port 6080) in a separate terminal.
|
||||
|
||||
## Compute Node (Hypervisor) Setup
|
||||
|
||||
|
|
@ -381,16 +381,17 @@ datasource:
|
|||
|
||||
### Serial Console (disabled by default)
|
||||
|
||||
The xterm.js serial console is served by `console/socketiod`, which does **not authenticate connections yet**: anyone who can reach its port (6081) can read and write a serial console that someone has opened. Until this is fixed, the serial console is disabled:
|
||||
`console/socketiod` does not authenticate connections yet, so the serial (xterm.js) console is disabled. To enable it on a trusted network:
|
||||
|
||||
- the console page shows "Serial console is disabled" for VMs with a `pty` console, and
|
||||
- `socketiod` refuses to start, and is not started by the bundled supervisor/systemd configs.
|
||||
1. In `webvirtcloud/settings.py`: `SERIAL_CONSOLE_ENABLED = True` and `SOCKETIO_PUBLIC_PORT = 80` (or `443`).
|
||||
2. Uncomment `location /socket.io/` in the nginx config.
|
||||
3. Set `autostart=true` for `[program:socketiod]` in the supervisor config, or `systemctl enable --now webvirt-socketiod`.
|
||||
|
||||
To enable it anyway on a trusted network, set `SERIAL_CONSOLE_ENABLED = True` in `webvirtcloud/settings.py`, set `autostart=true` for `[program:socketiod]` in the supervisor config (or `systemctl enable --now webvirt-socketiod`), and restrict access to port 6081 with a firewall. Existing installs whose `settings.py` predates this setting are treated as disabled.
|
||||
Existing installs: set `autostart=false` for `[program:socketiod]`, comment out `location /socket.io/` in nginx, and set `SOCKETIO_HOST = "127.0.0.1"` in `settings.py`.
|
||||
|
||||
### Reverse-Proxy & Port Forwarding
|
||||
|
||||
If WebVirtCloud runs behind a reverse proxy terminating SSL or forwarding port 80/443, set the public console ports in `webvirtcloud/settings.py` (defaults: 6080 for noVNC, 6081 for Socket.IO). The bundled nginx config already proxies `/novncd/` and `/socket.io/`:
|
||||
If WebVirtCloud runs behind a reverse proxy terminating SSL or forwarding port 80/443, set the public console ports in `webvirtcloud/settings.py` (defaults: 6080 for noVNC, 6081 for Socket.IO). The bundled nginx config already proxies `/novncd/`:
|
||||
|
||||
```python
|
||||
WS_PUBLIC_PORT = 80 # or 443
|
||||
|
|
|
|||
|
|
@ -27,12 +27,15 @@ server {
|
|||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
location /socket.io/ {
|
||||
proxy_pass http://wssocketiod;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
# Serial console (socketiod). Disabled by default: socketiod does not
|
||||
# authenticate connections yet. Uncomment only together with
|
||||
# SERIAL_CONSOLE_ENABLED = True, and only on a trusted network.
|
||||
#location /socket.io/ {
|
||||
# proxy_pass http://wssocketiod;
|
||||
# proxy_http_version 1.1;
|
||||
# proxy_set_header Upgrade $http_upgrade;
|
||||
# proxy_set_header Connection "upgrade";
|
||||
#}
|
||||
location /websockify {
|
||||
proxy_pass http://wsnovncd;
|
||||
proxy_http_version 1.1;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import os
|
|||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
|
|
@ -13,11 +14,10 @@ class SocketiodDisabledTestCase(unittest.TestCase):
|
|||
"""ROADMAP S-01: socketiod must refuse to start unless explicitly enabled."""
|
||||
|
||||
def test_socketiod_exits_when_serial_console_disabled(self):
|
||||
settings_dir = ROOT / "console" / "_test_settings"
|
||||
settings_dir.mkdir(exist_ok=True)
|
||||
try:
|
||||
(settings_dir / "__init__.py").write_text("")
|
||||
(settings_dir / "disabled.py").write_text(
|
||||
# The settings module lives in a temporary directory, so the test does
|
||||
# not write into the source tree (read-only checkouts, --parallel).
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
(Path(tmp) / "socketiod_disabled_settings.py").write_text(
|
||||
"from webvirtcloud.settings import * # noqa\n"
|
||||
"SERIAL_CONSOLE_ENABLED = False\n"
|
||||
"SOCKETIO_HOST = '127.0.0.1'\n"
|
||||
|
|
@ -25,8 +25,8 @@ class SocketiodDisabledTestCase(unittest.TestCase):
|
|||
)
|
||||
env = dict(
|
||||
os.environ,
|
||||
DJANGO_SETTINGS_MODULE="console._test_settings.disabled",
|
||||
PYTHONPATH=str(ROOT),
|
||||
DJANGO_SETTINGS_MODULE="socketiod_disabled_settings",
|
||||
PYTHONPATH=os.pathsep.join([tmp, str(ROOT)]),
|
||||
)
|
||||
# Other test modules import novncd, which sets SIGCHLD to SIG_IGN in
|
||||
# this process; with that, the child's exit status is lost (always 0).
|
||||
|
|
@ -44,14 +44,5 @@ class SocketiodDisabledTestCase(unittest.TestCase):
|
|||
self.fail("socketiod kept running although SERIAL_CONSOLE_ENABLED=False")
|
||||
finally:
|
||||
signal.signal(signal.SIGCHLD, previous_sigchld)
|
||||
self.assertNotEqual(result.returncode, 0, result.stdout + result.stderr)
|
||||
self.assertIn("SERIAL_CONSOLE_ENABLED", result.stderr)
|
||||
finally:
|
||||
for f in settings_dir.glob("*"):
|
||||
if f.is_file():
|
||||
f.unlink()
|
||||
for d in settings_dir.glob("__pycache__"):
|
||||
for f in d.glob("*"):
|
||||
f.unlink()
|
||||
d.rmdir()
|
||||
settings_dir.rmdir()
|
||||
self.assertNotEqual(result.returncode, 0, result.stdout + result.stderr)
|
||||
self.assertIn("SERIAL_CONSOLE_ENABLED", result.stderr)
|
||||
|
|
|
|||
|
|
@ -225,7 +225,9 @@ WS_CERT = None
|
|||
SERIAL_CONSOLE_ENABLED = False
|
||||
|
||||
SOCKETIO_PORT = 6081
|
||||
SOCKETIO_HOST = "0.0.0.0"
|
||||
# Listen on localhost only and reach socketiod through the nginx /socket.io/
|
||||
# location (set SOCKETIO_PUBLIC_PORT to 80 or 443 then).
|
||||
SOCKETIO_HOST = "127.0.0.1"
|
||||
|
||||
# Socketio public host
|
||||
SOCKETIO_PUBLIC_HOST = None
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue