niom-turn/docs/deploy_tls_lxc.md

2.9 KiB

Deployment: TLS (turns) in Proxmox LXC

This document describes a minimal, practical approach to deploy niom-turn as a TURN/TLS (turns:) server inside a Proxmox LXC container for an initial Internet-facing MVP.

Goals

  • Run niom-turn with a TLS listener (TCP/TLS 5349) and UDP listener (3478).
  • Ensure TLS certs are provisioned securely (Let's Encrypt or mounted files).
  • Harden minimal attack surface (firewall, user, systemd supervision).

Prerequisites

  • Proxmox VE host with public IPv4 address and a reserved port mapping for the LXC.
  • LXC template based on Debian/Ubuntu (minimal), with rust runtime or built binary copied in.

Ports

  • UDP 3478 — STUN/TURN (required for many clients).
  • TCP 5349 — TLS/TURN (turns).

Networking notes for LXC

  • Use a bridged interface so the LXC has a routable IP (recommended).
  • Alternatively, NAT the required ports from the Proxmox host to the LXC.

Certificates

  • Recommended: use Let's Encrypt with a reverse proxy or certbot on the host and mount the certs into the container at /etc/ssl/niom-turn/ (e.g. fullchain.pem and privkey.pem).
  • Alternatively, copy PEM certs into the LXC (owner root only). For testing, you can generate a self-signed cert with rcgen or openssl.

Systemd service (example)

Create /etc/systemd/system/niom-turn.service inside the container:

[Unit]
Description=niom-turn TURN server
After=network.target

[Service]
User=niom
Group=niom
WorkingDirectory=/opt/niom-turn
ExecStart=/opt/niom-turn/niom-turn --config /opt/niom-turn/appsettings.json
Restart=on-failure

[Install]
WantedBy=multi-user.target

Sample appsettings.json (mount next to binary)

{
  "server": {
    "bind": "0.0.0.0:3478",
    "tls_cert": "/etc/ssl/niom-turn/fullchain.pem",
    "tls_key": "/etc/ssl/niom-turn/privkey.pem"
  },
  "credentials": [
    { "username": "testuser", "password": "secretpassword" }
  ]
}

Firewall

  • Allow UDP 3478 and TCP 5349. If using UFW on the container host:
ufw allow proto udp from any to any port 3478
ufw allow proto tcp from any to any port 5349

Security recommendations (MVP)

  • Run the server as an unprivileged user (e.g. niom).
  • Mount TLS certs read-only and restrict permissions to the service user.
  • Monitor logs and open ports; add basic rate-limiting on host if available.
  • For production: use ephemeral credential minting and avoid long-lived plain passwords.

Validation steps

  1. Start server via systemd: systemctl start niom-turn and check journalctl -u niom-turn.
  2. From a client (or the host), run the included smoke_client to test the UDP path.
  3. For TLS: use openssl s_client -connect <your-lxc-ip>:5349 -servername <your-hostname> to verify the cert chain and that TCP connections are accepted.

If you want, I can prepare a systemd unit, a small packaging script, and CI steps that build and copy the binary into a release tarball suitable for deploying into the LXC. Let me know which level of automation you prefer.