bluebluesodaandCommandCodeBot c0351ff8d8 fix: harden IPv6 pass-through and unprivileged panel found by e2e testing
Strict end-to-end testing against a real Incus 7 host with IPv6
pass-through enabled surfaced several issues, all fixed here:

- setup: default profile must carry root+eth0 devices even when Incus
  was already initialized (preseed may leave it empty); profile devices
  are now ensured on every install (scripts/10-incus.sh).
- IPv6 bridge route: Incus 7.0 does not auto-create the bridge's prefix
  route when the external interface already has one, which broke the
  per-container /112 routes ("no route to host"). SetupIPv6Bridge now
  adds it explicitly, plus a fixed fe80::1 link-local gateway that the
  dnsmasq RA advertises to containers (ipv6_filtering only permits NDP
  to that address).
- RHEL IPv6: the helper now fully staticizes IPv6 — learn the gateway
  from RA, disable RA processing (accept_ra=0), drop SLAAC/dynamic
  addresses (they fall outside the routed /112 and get filtered), pin
  the deterministic /128 + a static default route with a preferred
  source, and wait for DAD so the route add cannot fail on a tentative
  source. The unit retries (Restart=on-failure) until converged.
- provisioning race: wait for systemd to be ready inside the container
  before hostnamectl/systemctl (4/10 adds failed with "Failed to
  connect to system scope bus"); same wait in the IPv6 script.
- traefik permissions: the unprivileged panel could not write
  /etc/traefik/dynamic (parent dir is root:traefik 750). vps and
  traefik users are now cross-linked into each other's groups and the
  dynamic dir is owned by vps (scripts/30-traefik.sh, ensureVPSUser).
- ndppd.conf: pre-created and chowned to vps so the panel can render it
  (reinstall failed with "permission denied").
- sudoers: allow `ip -6 addr add/del` for the bridge gateway setup.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-14 05:29:13 +00:00

Vpsmgr Lite

Warning ⚠️ The "VMs" this project creates are LXC containers, not real virtual machines. Their isolation and security are far weaker than other virtualization approaches (KVM/QEMU, etc.). A kernel-level or container escape would affect the host and every tenant. Security risk is yours to accept — do not run untrusted or high-security workloads on a shared host.

简体中文 · Docs

A toy LXC hosting panel for small machines (≤ 4 GB RAM, small VPS): one Debian 13 container per user, managed from a web panel (start/stop/restart/reinstall), with automatic NAT4 port forwarding and 80/443 per-domain proxying by Traefik. Optional IPv6 pass-through (no NAT). The panel is a single small Go binary and the container image stays slim — storage and memory are treated as scarce.

Install notes: shared IPv4 inbound is always ON by default (flip it later with vps config set net.v4_forward true|false); the only network choice the installer asks for is the container subnet's second octet. Port 25 (SMTP) is always blocked for containers, both directions — anti-spam, no toggle.

Install

Minimum: Debian 12/13 or Ubuntu 22.04/24.04/26.04 (bare metal or KVM), 1 core, 1.5G RAM, 10G free disk, and root access

Both amd64 and arm64 are supported; testing has primarily been done on amd64.

git clone https://github.com/bluebluesoda/lxc-hosting.git && cd lxc-hosting
sudo ./install.sh                  # install the stable prebuilt binary
#sudo ./install.sh --local-build   # force a local build from source

The installer configures the Zabbly Incus LTS repository and installs Incus 7 LTS (Debian packages — the same repo serves Ubuntu, so the panel is portable across both).

To enable IPv6 pass-through, make sure the host has been assigned an entire routed prefix. Ask your provider, or use the check script in this repository for an informal test.

Be sure the entire IPv6 prefix works before installing with IPv6 support.

bash check-ipv6-support.sh # IPv6 test script

Run vps panel-url after installation to get the full panel address — https://<IP>:<port>/<random-path> (the port is a random free one in 2000-9999). This random path is the panel's only entry point.

Optional: extra OS images

The default is Debian 13. To let users reinstall their container with a RHEL-family system, run (once, as root) the optional image builder — it is NOT run by install.sh so small boxes stay lean:

sudo bash scripts/60-rhel-image.sh          # Alma 9
sudo bash scripts/60-rhel-image.sh rocky     # Rocky 9

Reinstall then offers the built images as a choice (always, even with only the default). The image is slimmed and the base image deleted, same as the Debian one.

Usage

vps add <name> [--cpu N] [--mem NG] [--disk NG]   # default 1 core / 1G / 10G; cpu = whole cores (>=1) or a decimal 0.1..0.9; password is auto-generated and shown once
vps quota <name> [--cpu N] [--mem N] [--disk NG]  # disk can only grow
vps passwd <name>                                 # reissue user panel password (shown once)
vps list [name]                                   # all users, or one user's detail
vps power <name> start|stop|restart
vps del <name>
vps panel-url
vps config set net.v4_forward true|false   # shared IPv4 inbound: false = IPv6-only containers

Users can set a custom init script in their panel — it runs as root inside their container after a reinstall (output at /var/log/vpsmgr-init.log), for cloud-provider-style first-boot automation.

Admins can set a per-user monthly bandwidth quota (GiB, upload + download); a container that exceeds it is rate-limited to 1Mbps both directions. The limit is applied live via Incus (tc qdiscs) — no container restart.

Domains can opt into PROXY protocol v2 (the 443 TLS passthrough reports the visitor IP to the backend, which must support it; HTTP/80 keeps normal X-Forwarded-For headers). An admin domain management page lists every domain with its owner and last-modified time (UTC, shown in the browser's timezone) and can toggle the setting or delete domains.

An audit log records resource-heavy user actions — power, reinstall, root password reset, domain config changes. Rows are attributed to the acting username, or 000+<username> when an admin acts on that user's resources. The admin audit page loads it in 500-row chunks with infinite scroll; the latest 5000 entries are kept.

Config

/etc/vpsmgr/config.yaml (auto-generated at install) — the defaults are not meant to be changed. The sanctioned interface is vps config list/set/help, which validates every change and refuses immutable fields. Reference: docs/configuration.md.

Uninstall

sudo ./uninstall.sh          # remove software, keep config/db/containers
sudo ./uninstall.sh --purge  # also delete config/db, containers, pool, Incus

Documentation

Technical detail lives in docs/ (English): index, plus AGENTS.md for AI coding agents.

Screenshots

Admin panel:

Admin panel

User panel:

User panel

S
Description
a panel to share lxc containers [开源]一键开小鸡切小鸡面板,共享v4独立v6小鸡,支持443无感共享,流量限制,自助重装!
Readme Apache-2.0
2.7 MiB
0 Stars 1 Watchers 0 Forks
Languages
Go 71.2%
HTML 14.7%
Shell 11.7%
JavaScript 2.4%