feat(install): support disabling IPv4 forwarding
- add --disable-v4forward with explicit confirmation\n- skip reserved-port checks and keep Traefik stopped for IPv6-only installs\n- document dedicated-host requirements and sync config references
This commit is contained in:
1 parent
6d897cc1bb
commit
97396589f5
7 files changed
+81
-9
No files matched your search
@@ -21,6 +21,8 @@ A lightweight Incus container hosting panel for small VPS instances and low-memo
|
||||
|
||||
Ubuntu 24.04 is recommended; Ubuntu 22+ and Debian 12+ also work. Debian requires a kernel-module build and takes longer to install.
|
||||
|
||||
Unless you have checked the existing services and network configuration, treat the installer as a fresh, dedicated-host installer. Do not run it directly on a personal host that already serves other workloads. It installs and configures Incus, ZFS (by default), nftables, Traefik, systemd units, and a container bridge; with IPv4 inbound forwarding enabled it also requires ports `80/443`, `10000-29999`, and `30000-31999` to be available, and may disable conflicting UFW configuration. The installer does not uninstall your applications, but its ports, bridge, and firewall policy can conflict with existing services.
|
||||
|
||||
Recommended minimum: 1 CPU core, 1 GB RAM, 15 GB of free disk space, and root access. Both amd64 and arm64 are supported; testing has focused mainly on amd64.
|
||||
|
||||
```sh
|
||||
@@ -33,6 +35,14 @@ sudo ./install.sh # download the latest prebuilt binary
|
||||
|
||||
The installer first downloads the prebuilt binary from GitHub Releases. If that fails, it falls back to a local build. `--local-build` always rebuilds from source. If `--update` cannot download the release, the existing binary is left untouched.
|
||||
|
||||
If the host already runs other public services and you only need IPv6 inbound access, without IPv4 SSH/port forwarding, use:
|
||||
|
||||
```sh
|
||||
sudo ./install.sh --disable-v4forward
|
||||
```
|
||||
|
||||
This option asks for confirmation at the beginning. Once confirmed, it writes `net.v4_forward=false`, skips vpsmgr's reserved-port check, and only needs one randomly selected panel entry port. Traefik is still installed but remains stopped. IPv4 inbound forwarding can later be restored with `vps config set net.v4_forward true`.
|
||||
|
||||
ZFS is the default storage backend. For disposable test machines, you can explicitly choose the `dir` backend. It does not provide ZFS quotas, snapshots, or cloning:
|
||||
|
||||
```sh
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
推荐使用 Ubuntu 24.04。Ubuntu 22+ / Debian 12+ 均可使用;Debian 需要编译内核模块,安装时间较长。
|
||||
|
||||
除非你明确检查过现有服务与网络配置,否则请把安装器视为“全新、专用主机”安装器,不要直接在正在运行其他业务的自用主机上执行。安装器会安装并配置 Incus、ZFS(默认)、nftables、Traefik、systemd 服务和容器网桥;启用 v4 入站转发时还要求 `80/443`、`10000-29999`、`30000-31999` 端口可用,并可能停用冲突的 UFW 配置。安装器不会卸载你的业务程序,但端口、网桥和防火墙策略可能与已有服务冲突。
|
||||
|
||||
最低建议:1 核、1 GB 内存、15 GB 可用磁盘空间,以及 root 权限。amd64 和 arm64 均支持,主要在 amd64 上测试。
|
||||
|
||||
**从预编译安装**
|
||||
@@ -38,6 +40,14 @@ git clone --depth 1 https://github.com/bluebluesoda/vpsmgr.git && cd vpsmgr
|
||||
sudo ./install.sh --local-build
|
||||
```
|
||||
|
||||
如果这台主机已有其他公网服务,且你只需要 IPv6 入站、不需要 v4 SSH/端口转发,可以使用:
|
||||
|
||||
```sh
|
||||
sudo ./install.sh --disable-v4forward
|
||||
```
|
||||
|
||||
该参数会在安装开始时要求确认;确认后写入 `net.v4_forward=false`,跳过 vpsmgr 保留端口检查,只随机选择一个面板入口端口。Traefik 仍会安装但不会启动。以后可用 `vps config set net.v4_forward true` 恢复 IPv4 入站转发。
|
||||
|
||||
### IPv6
|
||||
|
||||
IPv6 直通默认关闭。交互式安装会询问是否启用,并根据网络条件提供以下模式:
|
||||
|
||||
@@ -12,7 +12,7 @@ panel:
|
||||
url_path: AUTO # 10-char random [a-zA-Z0-9_-] secret prefix, generated once at install
|
||||
admin_url_path: AUTO # 10-char random secret prefix for the ADMIN panel; can be
|
||||
# changed later or set to empty to disable the admin panel
|
||||
admin_pass_hash: AUTO # bcrypt hash of the admin panel password; generated at install,
|
||||
admin_pass_hash: AUTO # bcrypt hash of the admin panel password; generated at install,
|
||||
# reset via `vps admin-passwd`. No admin username — password only.
|
||||
|
||||
net:
|
||||
@@ -28,14 +28,22 @@ net:
|
||||
# SSH/port-block DNAT and traefik/domains disabled
|
||||
# (NAT4 outbound kept). Toggle at runtime: vps config set net.v4_forward true|false
|
||||
ext_if: AUTO # detected from default route
|
||||
ipv6_mode: none # fixed at install: none, prefix, or pool
|
||||
ipv6_subnet: "" # optional: global prefix for IPv6 pass-through, e.g. "2602:fada:6::/64".
|
||||
# /64 or shorter works (e.g. /56); a provider /80 slice like
|
||||
# /64 or shorter uses the first /64; a provider /80 slice like
|
||||
# "2406:da14:1dd2:a807:753a::/80" is also supported.
|
||||
# empty = IPv6 disabled (default). Containers get global
|
||||
# addresses via SLAAC; no NAT; set at install time.
|
||||
ipv6_pool: [] # optional (pool mode): bare global IPv6 addresses or /128;
|
||||
# addresses are assigned to containers until they are deleted.
|
||||
|
||||
incus:
|
||||
image: "vpsmgr/debian-sshd"
|
||||
image_fallback: "images:debian/13"
|
||||
pool: vpsmgr
|
||||
bridge: incusbr0
|
||||
socket: "/var/lib/incus/unix.socket"
|
||||
swap_ratio: 0.5 # 0 = no container swap; 0.5 = memory allowance / 2
|
||||
|
||||
snapshots:
|
||||
limit: 1 # 0 disables new snapshots
|
||||
+17
-6
@@ -5,6 +5,13 @@ root-only read/write). The `VPSMGR_CONFIG` env var points the `vps` binary at
|
||||
another path; the shell install/uninstall scripts always use
|
||||
`/etc/vpsmgr/config.yaml`.
|
||||
|
||||
The installer is intended for a fresh, dedicated host unless existing services,
|
||||
ports, bridges, UFW, and firewall rules have been checked. For a host that must
|
||||
keep other public services and only needs IPv6 inbound access, install with
|
||||
`./install.sh --disable-v4forward`; this requires an explicit confirmation,
|
||||
skips vpsmgr's reserved-port check, writes `net.v4_forward=false`, and leaves
|
||||
Traefik installed but stopped.
|
||||
|
||||
**Editing config.yaml by hand is discouraged.** The sanctioned interface is
|
||||
`vps config list` / `vps config set` / `vps config help`, which validate every
|
||||
change and refuse immutable fields. A raw YAML edit still works but is not
|
||||
@@ -21,7 +28,7 @@ same table; `vps config list` shows the live values with this annotation.
|
||||
| `panel.listen` | operator | `systemctl restart vps` | a FRESH install picks a random free port in 2000-9999 |
|
||||
| `panel.cert` | operator | restart panel | TLS certificate path |
|
||||
| `panel.key` | operator | restart panel | TLS private key path |
|
||||
| `panel.db` | operator | restart panel | SQLite database path |
|
||||
| `panel.db` | operator | re-run `vps install` | SQLite database path |
|
||||
| `panel.public_ip` | operator | re-run `vps install` | NIC IPv4 used by firewall/routing; cert is regenerated |
|
||||
| `panel.display_ip` | operator | restart panel | address shown to users (panel URL / SSH hints); any string without spaces (IP or domain), or empty = fall back to `public_ip` |
|
||||
| `panel.session_days` | operator | restart panel | login session lifetime (days) |
|
||||
@@ -34,19 +41,19 @@ same table; `vps config list` shows the live values with this annotation.
|
||||
| `net.ext_if` | operator | re-run `vps install` | external NIC (auto-detected from default route) |
|
||||
| `net.ipv6_subnet` | operator | re-run `vps install` | global IPv6 prefix for pass-through, e.g. `2602:fada:6::/64`; empty = disabled (does not remove IPv6 state already applied, see note below) |
|
||||
| `net.ipv6_mode` | **fixed at install** | — | IPv6 allocation mode: `none` / `prefix` (/112 blocks) / `pool` (per-container address) |
|
||||
| `net.ipv6_pool` | operator | applied immediately | pool-mode address list (bare global addresses or `/128`); editable via the admin panel's IPv6 Pool page |
|
||||
| `net.ipv6_pool` | operator | `vps config set` needs `--apply`; admin-panel changes apply immediately | pool-mode address list (bare global addresses or `/128`); editable via the admin panel's IPv6 Pool page |
|
||||
| `incus.image` | operator | next `vps add` / reinstall | container image alias |
|
||||
| `incus.image_fallback` | operator | next `vps add` / reinstall | fallback remote image |
|
||||
| `incus.pool` | **fixed at install** | — | storage pool |
|
||||
| `incus.bridge` | **fixed at install** | — | managed bridge |
|
||||
| `incus.socket` | operator | restart panel | Incus daemon Unix socket |
|
||||
| `incus.swap_ratio` | operator | **applied immediately** | swap granted to each container as a multiple of its memory limit (`limits.memory.swap = limits.memory × ratio`); `0` disables container swap. Setting it re-applies the allowance to **all existing containers** (no restart) |
|
||||
| `snapshots.limit` | operator | restart panel | max snapshots a user may keep per container (`0` = default `1`) |
|
||||
| `snapshots.limit` | operator | restart panel | max snapshots a user may keep per container (`0` = disable new snapshots) |
|
||||
|
||||
### How "fixed at install" is enforced
|
||||
|
||||
Fields marked **fixed at install** (`net.subnet`, `net.gateway`, `incus.pool`,
|
||||
`incus.bridge`, `panel.url_path`) are snapshotted into the DB settings table on
|
||||
`incus.bridge`, `panel.url_path`, `net.ipv6_mode`) are snapshotted into the DB settings table on
|
||||
the first `vps install`. Every later `vps install` and `vps serve` compares the
|
||||
live config against that snapshot and **refuses to run** if any of them drifted
|
||||
— `vps config set` also refuses them up front. The user panel path
|
||||
@@ -91,7 +98,7 @@ net:
|
||||
ext_if: AUTO # external NIC, auto-detected from the default route
|
||||
ipv6_mode: "" # IPv6 allocation mode: none / prefix / pool (fixed at install)
|
||||
ipv6_subnet: "" # optional: global prefix for IPv6 pass-through, e.g. "2602:fada:6::/64"
|
||||
# (/64 or shorter, incl. provider /80 slices like
|
||||
# (/64 or shorter uses the first /64; provider /80 slices like
|
||||
# "2406:da14:1dd2:a807:753a::/80"); empty = disabled (default),
|
||||
# but does not remove IPv6 state already applied
|
||||
ipv6_pool: [] # optional (pool mode): the /128 addresses containers are
|
||||
@@ -108,6 +115,9 @@ incus:
|
||||
# memory limit (0 = no swap; 0.5 = a 1 GiB
|
||||
# container may use 512 MiB host swap);
|
||||
# applied to all containers immediately on set
|
||||
|
||||
snapshots:
|
||||
limit: 1 # 0 disables new snapshots
|
||||
```
|
||||
|
||||
## Port scheme (fixed)
|
||||
@@ -159,7 +169,8 @@ goes away when the panel is uninstalled.
|
||||
change them after first install.
|
||||
- `net.ipv6_subnet` must be a **global** (non-ULA) IPv6 CIDR with an explicit
|
||||
prefix length — a bare address is rejected, never silently assumed `/64`.
|
||||
Valid range is `/48`..`/80` (see [ipv6.md](ipv6.md)).
|
||||
The validator accepts a global prefix of `/80` or shorter; `/48`..`/80` are
|
||||
the documented operational range (see [ipv6.md](ipv6.md)).
|
||||
- `net.ipv6_mode` is fixed at install and immutable (like `net.subnet`):
|
||||
`none` (pure IPv4), `prefix` (classic /112 blocks), `pool` (per-container
|
||||
address from `net.ipv6_pool`). Switching modes would renumber containers.
|
||||
|
||||
+28
@@ -4,19 +4,29 @@
|
||||
# ./install.sh # default: download latest prebuilt release binary (fallback: local build)
|
||||
# ./install.sh --local-build # force local Go compilation of the panel binary
|
||||
# ./install.sh --update # force re-download of the prebuilt release binary over an existing one
|
||||
# ./install.sh --disable-v4forward # install IPv6-only inbound policy; skip reserved-port checks
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
ROOT="$PWD"
|
||||
|
||||
BUILD_MODE=release
|
||||
DISABLE_V4FORWARD=0
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--local-build) BUILD_MODE=local ;;
|
||||
--update) BUILD_MODE=update ;;
|
||||
--disable-v4forward) DISABLE_V4FORWARD=1 ;;
|
||||
esac
|
||||
done
|
||||
export VPSMGR_BUILD_MODE="$BUILD_MODE"
|
||||
if [[ "$DISABLE_V4FORWARD" == "1" ]]; then
|
||||
# This explicit installer choice overrides an adopted config and any
|
||||
# VPSMGR_V4_FORWARD value inherited from the caller. 00-check.sh uses the
|
||||
# separate marker to skip checks for ports that vpsmgr will not expose.
|
||||
export VPSMGR_V4_FORWARD=0
|
||||
export VPSMGR_DISABLE_V4FORWARD=1
|
||||
fi
|
||||
|
||||
# Storage backend: zfs (default) or dir. dir has no quotas/snapshots/clones —
|
||||
# only meant for throwaway test boxes. Never fall back automatically.
|
||||
@@ -31,6 +41,24 @@ if [[ $EUID -ne 0 ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$DISABLE_V4FORWARD" == "1" ]]; then
|
||||
echo
|
||||
echo "!! --disable-v4forward: install with IPv4 inbound forwarding disabled !!"
|
||||
echo " Containers will have no IPv4 SSH/port DNAT; Traefik will be installed but stopped."
|
||||
echo " Reserved vpsmgr port checks will be skipped. You can re-enable later with:"
|
||||
echo " vps config set net.v4_forward true"
|
||||
if [[ ! -t 0 ]]; then
|
||||
echo "error: --disable-v4forward requires an interactive confirmation" >&2
|
||||
exit 1
|
||||
fi
|
||||
read -r -p "Continue with IPv4 inbound disabled? [Y/n] " V4_CONFIRM
|
||||
case "$V4_CONFIRM" in
|
||||
''|y|Y|yes|YES) ;;
|
||||
n|N|no|NO) echo "[install] aborted by user"; exit 1 ;;
|
||||
*) echo "error: please answer Y or n" >&2; exit 1 ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Local build: make it obvious WHICH branch will be compiled, and give the user
|
||||
# a chance to abort — some people want a dev build but end up building stable.
|
||||
if [[ "$BUILD_MODE" == "local" ]]; then
|
||||
|
||||
+2
-1
@@ -10,6 +10,7 @@
|
||||
# Supported args (passed straight through to install.sh):
|
||||
# --update re-download the latest prebuilt release binary over an existing one
|
||||
# --local-build force local Go compilation of the panel binary
|
||||
# --disable-v4forward install with IPv4 inbound forwarding disabled
|
||||
# Env:
|
||||
# VPSMGR_STORAGE=zfs|dir storage backend (default zfs)
|
||||
# VPSMGR_BRANCH=<branch> branch/tag to fetch (default main)
|
||||
@@ -32,7 +33,7 @@ fi
|
||||
ARGS=()
|
||||
for a in "$@"; do
|
||||
case "$a" in
|
||||
--update|--local-build) ARGS+=("$a") ;;
|
||||
--update|--local-build|--disable-v4forward) ARGS+=("$a") ;;
|
||||
*) echo "oneclick.sh: ignoring unknown arg '$a'" >&2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
@@ -197,6 +197,9 @@ fi
|
||||
# panel and traefik are already running and owned by vpsmgr — those listeners
|
||||
# are excluded by process name. Checks TCP and UDP (the user port block is
|
||||
# DNAT-ed for both).
|
||||
if [[ "${VPSMGR_DISABLE_V4FORWARD:-0}" == "1" ]]; then
|
||||
log "v4 forwarding disabled by installer — skipping reserved port checks"
|
||||
else
|
||||
port_reserved(){
|
||||
local p="$1"
|
||||
[[ "$p" == "80" || "$p" == "443" ]] && return 0
|
||||
@@ -226,6 +229,7 @@ $CONFLICTS
|
||||
Free these ports (or remove the programs above) and re-run install."
|
||||
fi
|
||||
log "reserved ports are free"
|
||||
fi
|
||||
|
||||
# --- detect public ip / ext iface ---
|
||||
# ext iface: prefer the IPv4 default route, then the IPv6 default route (covers
|
||||
|
||||
Reference in new issue
Block a user